Alexey Edelev пре 2 година
родитељ
комит
4afce80e73
10 измењених фајлова са 112 додато и 658 уклоњено
  1. 5 3
      build.sh
  2. 0 546
      common/gostfix.pb.go
  3. 2 2
      common/gostfix.proto
  4. 5 4
      config/config.go
  5. 30 4
      db/db.go
  6. 9 8
      go.mod
  7. 56 87
      go.sum
  8. 1 1
      main.go
  9. 3 2
      scanner/mailscanner.go
  10. 1 1
      views

+ 5 - 3
build.sh

@@ -1,21 +1,23 @@
 export GOBIN=$(go env GOPATH)/bin
 export PATH=$PATH:$GOBIN
 export RPC_PATH=common
+
+go env
 go install google.golang.org/protobuf/compiler/protogen
 go install github.com/amsokol/protoc-gen-gotag
 
 # mkdir -p $RPC_PATH
 rm -f $RPC_PATH/*.pb.go
-protoc -I$RPC_PATH --go_out=plugins=grpc:$RPC_PATH $RPC_PATH/gostfix.proto
+protoc -I$RPC_PATH --go_out=plugins=grpc:$PWD $RPC_PATH/gostfix.proto
 
 protoc -I$RPC_PATH --gotag_out=xxx="bson+\"-\"",output_path=$RPC_PATH:. $RPC_PATH/gostfix.proto
 
-echo "Installing data"
+#echo "Installing data"
 rm -rf data
 mkdir data
 cp -a main.ini data/
 cp -a main.cf data/
-cp -a vmailbox.db data/
+#cp -a vmailbox.db data/
 cp -a web/assets data/
 cp -a web/css data/
 cp -a web/js data/

+ 0 - 546
common/gostfix.pb.go

@@ -1,546 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: gostfix.proto
-
-package common
-
-import (
-	fmt "fmt"
-	proto "github.com/golang/protobuf/proto"
-	math "math"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
-
-type MailBody struct {
-	PlainText            string              `protobuf:"bytes,1,opt,name=plainText,proto3" json:"plainText,omitempty"`
-	RichText             string              `protobuf:"bytes,2,opt,name=richText,proto3" json:"richText,omitempty"`
-	Attachments          []*AttachmentHeader `protobuf:"bytes,3,rep,name=attachments,proto3" json:"attachments,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}            `json:"-" bson:"-"`
-	XXX_unrecognized     []byte              `json:"-" bson:"-"`
-	XXX_sizecache        int32               `json:"-" bson:"-"`
-}
-
-func (m *MailBody) Reset()         { *m = MailBody{} }
-func (m *MailBody) String() string { return proto.CompactTextString(m) }
-func (*MailBody) ProtoMessage()    {}
-func (*MailBody) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{0}
-}
-
-func (m *MailBody) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_MailBody.Unmarshal(m, b)
-}
-func (m *MailBody) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_MailBody.Marshal(b, m, deterministic)
-}
-func (m *MailBody) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_MailBody.Merge(m, src)
-}
-func (m *MailBody) XXX_Size() int {
-	return xxx_messageInfo_MailBody.Size(m)
-}
-func (m *MailBody) XXX_DiscardUnknown() {
-	xxx_messageInfo_MailBody.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MailBody proto.InternalMessageInfo
-
-func (m *MailBody) GetPlainText() string {
-	if m != nil {
-		return m.PlainText
-	}
-	return ""
-}
-
-func (m *MailBody) GetRichText() string {
-	if m != nil {
-		return m.RichText
-	}
-	return ""
-}
-
-func (m *MailBody) GetAttachments() []*AttachmentHeader {
-	if m != nil {
-		return m.Attachments
-	}
-	return nil
-}
-
-type MailHeader struct {
-	From                 string   `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
-	To                   string   `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"`
-	Cc                   string   `protobuf:"bytes,3,opt,name=cc,proto3" json:"cc,omitempty"`
-	Bcc                  string   `protobuf:"bytes,4,opt,name=bcc,proto3" json:"bcc,omitempty"`
-	Date                 int64    `protobuf:"zigzag64,5,opt,name=date,proto3" json:"date,omitempty"`
-	Subject              string   `protobuf:"bytes,6,opt,name=subject,proto3" json:"subject,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *MailHeader) Reset()         { *m = MailHeader{} }
-func (m *MailHeader) String() string { return proto.CompactTextString(m) }
-func (*MailHeader) ProtoMessage()    {}
-func (*MailHeader) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{1}
-}
-
-func (m *MailHeader) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_MailHeader.Unmarshal(m, b)
-}
-func (m *MailHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_MailHeader.Marshal(b, m, deterministic)
-}
-func (m *MailHeader) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_MailHeader.Merge(m, src)
-}
-func (m *MailHeader) XXX_Size() int {
-	return xxx_messageInfo_MailHeader.Size(m)
-}
-func (m *MailHeader) XXX_DiscardUnknown() {
-	xxx_messageInfo_MailHeader.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MailHeader proto.InternalMessageInfo
-
-func (m *MailHeader) GetFrom() string {
-	if m != nil {
-		return m.From
-	}
-	return ""
-}
-
-func (m *MailHeader) GetTo() string {
-	if m != nil {
-		return m.To
-	}
-	return ""
-}
-
-func (m *MailHeader) GetCc() string {
-	if m != nil {
-		return m.Cc
-	}
-	return ""
-}
-
-func (m *MailHeader) GetBcc() string {
-	if m != nil {
-		return m.Bcc
-	}
-	return ""
-}
-
-func (m *MailHeader) GetDate() int64 {
-	if m != nil {
-		return m.Date
-	}
-	return 0
-}
-
-func (m *MailHeader) GetSubject() string {
-	if m != nil {
-		return m.Subject
-	}
-	return ""
-}
-
-type Mail struct {
-	Header               *MailHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
-	Body                 *MailBody   `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}    `json:"-" bson:"-"`
-	XXX_unrecognized     []byte      `json:"-" bson:"-"`
-	XXX_sizecache        int32       `json:"-" bson:"-"`
-}
-
-func (m *Mail) Reset()         { *m = Mail{} }
-func (m *Mail) String() string { return proto.CompactTextString(m) }
-func (*Mail) ProtoMessage()    {}
-func (*Mail) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{2}
-}
-
-func (m *Mail) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Mail.Unmarshal(m, b)
-}
-func (m *Mail) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Mail.Marshal(b, m, deterministic)
-}
-func (m *Mail) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Mail.Merge(m, src)
-}
-func (m *Mail) XXX_Size() int {
-	return xxx_messageInfo_Mail.Size(m)
-}
-func (m *Mail) XXX_DiscardUnknown() {
-	xxx_messageInfo_Mail.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Mail proto.InternalMessageInfo
-
-func (m *Mail) GetHeader() *MailHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *Mail) GetBody() *MailBody {
-	if m != nil {
-		return m.Body
-	}
-	return nil
-}
-
-type Attachment struct {
-	Header               *AttachmentHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
-	Data                 []byte            `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-" bson:"-"`
-	XXX_unrecognized     []byte            `json:"-" bson:"-"`
-	XXX_sizecache        int32             `json:"-" bson:"-"`
-}
-
-func (m *Attachment) Reset()         { *m = Attachment{} }
-func (m *Attachment) String() string { return proto.CompactTextString(m) }
-func (*Attachment) ProtoMessage()    {}
-func (*Attachment) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{3}
-}
-
-func (m *Attachment) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Attachment.Unmarshal(m, b)
-}
-func (m *Attachment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Attachment.Marshal(b, m, deterministic)
-}
-func (m *Attachment) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Attachment.Merge(m, src)
-}
-func (m *Attachment) XXX_Size() int {
-	return xxx_messageInfo_Attachment.Size(m)
-}
-func (m *Attachment) XXX_DiscardUnknown() {
-	xxx_messageInfo_Attachment.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Attachment proto.InternalMessageInfo
-
-func (m *Attachment) GetHeader() *AttachmentHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *Attachment) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-type AttachmentHeader struct {
-	Id                   string   `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	FileName             string   `protobuf:"bytes,2,opt,name=fileName,proto3" json:"fileName,omitempty"`
-	ContentType          string   `protobuf:"bytes,3,opt,name=contentType,proto3" json:"contentType,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *AttachmentHeader) Reset()         { *m = AttachmentHeader{} }
-func (m *AttachmentHeader) String() string { return proto.CompactTextString(m) }
-func (*AttachmentHeader) ProtoMessage()    {}
-func (*AttachmentHeader) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{4}
-}
-
-func (m *AttachmentHeader) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AttachmentHeader.Unmarshal(m, b)
-}
-func (m *AttachmentHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AttachmentHeader.Marshal(b, m, deterministic)
-}
-func (m *AttachmentHeader) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AttachmentHeader.Merge(m, src)
-}
-func (m *AttachmentHeader) XXX_Size() int {
-	return xxx_messageInfo_AttachmentHeader.Size(m)
-}
-func (m *AttachmentHeader) XXX_DiscardUnknown() {
-	xxx_messageInfo_AttachmentHeader.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AttachmentHeader proto.InternalMessageInfo
-
-func (m *AttachmentHeader) GetId() string {
-	if m != nil {
-		return m.Id
-	}
-	return ""
-}
-
-func (m *AttachmentHeader) GetFileName() string {
-	if m != nil {
-		return m.FileName
-	}
-	return ""
-}
-
-func (m *AttachmentHeader) GetContentType() string {
-	if m != nil {
-		return m.ContentType
-	}
-	return ""
-}
-
-type UserInfo struct {
-	User                 string   `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
-	FullName             string   `protobuf:"bytes,2,opt,name=fullName,proto3" json:"fullName,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *UserInfo) Reset()         { *m = UserInfo{} }
-func (m *UserInfo) String() string { return proto.CompactTextString(m) }
-func (*UserInfo) ProtoMessage()    {}
-func (*UserInfo) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{5}
-}
-
-func (m *UserInfo) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_UserInfo.Unmarshal(m, b)
-}
-func (m *UserInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_UserInfo.Marshal(b, m, deterministic)
-}
-func (m *UserInfo) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_UserInfo.Merge(m, src)
-}
-func (m *UserInfo) XXX_Size() int {
-	return xxx_messageInfo_UserInfo.Size(m)
-}
-func (m *UserInfo) XXX_DiscardUnknown() {
-	xxx_messageInfo_UserInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UserInfo proto.InternalMessageInfo
-
-func (m *UserInfo) GetUser() string {
-	if m != nil {
-		return m.User
-	}
-	return ""
-}
-
-func (m *UserInfo) GetFullName() string {
-	if m != nil {
-		return m.FullName
-	}
-	return ""
-}
-
-type Frame struct {
-	Skip                 int32    `protobuf:"zigzag32,1,opt,name=skip,proto3" json:"skip,omitempty"`
-	Limit                int32    `protobuf:"zigzag32,2,opt,name=limit,proto3" json:"limit,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *Frame) Reset()         { *m = Frame{} }
-func (m *Frame) String() string { return proto.CompactTextString(m) }
-func (*Frame) ProtoMessage()    {}
-func (*Frame) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{6}
-}
-
-func (m *Frame) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Frame.Unmarshal(m, b)
-}
-func (m *Frame) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Frame.Marshal(b, m, deterministic)
-}
-func (m *Frame) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Frame.Merge(m, src)
-}
-func (m *Frame) XXX_Size() int {
-	return xxx_messageInfo_Frame.Size(m)
-}
-func (m *Frame) XXX_DiscardUnknown() {
-	xxx_messageInfo_Frame.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Frame proto.InternalMessageInfo
-
-func (m *Frame) GetSkip() int32 {
-	if m != nil {
-		return m.Skip
-	}
-	return 0
-}
-
-func (m *Frame) GetLimit() int32 {
-	if m != nil {
-		return m.Limit
-	}
-	return 0
-}
-
-type Folder struct {
-	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Custom               bool     `protobuf:"varint,2,opt,name=custom,proto3" json:"custom,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *Folder) Reset()         { *m = Folder{} }
-func (m *Folder) String() string { return proto.CompactTextString(m) }
-func (*Folder) ProtoMessage()    {}
-func (*Folder) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{7}
-}
-
-func (m *Folder) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Folder.Unmarshal(m, b)
-}
-func (m *Folder) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Folder.Marshal(b, m, deterministic)
-}
-func (m *Folder) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Folder.Merge(m, src)
-}
-func (m *Folder) XXX_Size() int {
-	return xxx_messageInfo_Folder.Size(m)
-}
-func (m *Folder) XXX_DiscardUnknown() {
-	xxx_messageInfo_Folder.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Folder proto.InternalMessageInfo
-
-func (m *Folder) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *Folder) GetCustom() bool {
-	if m != nil {
-		return m.Custom
-	}
-	return false
-}
-
-type FolderStat struct {
-	Folder               string   `protobuf:"bytes,1,opt,name=folder,proto3" json:"folder,omitempty"`
-	Total                uint32   `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
-	Unread               uint32   `protobuf:"varint,3,opt,name=unread,proto3" json:"unread,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
-	XXX_unrecognized     []byte   `json:"-" bson:"-"`
-	XXX_sizecache        int32    `json:"-" bson:"-"`
-}
-
-func (m *FolderStat) Reset()         { *m = FolderStat{} }
-func (m *FolderStat) String() string { return proto.CompactTextString(m) }
-func (*FolderStat) ProtoMessage()    {}
-func (*FolderStat) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0ab36b6dc6e1dcaa, []int{8}
-}
-
-func (m *FolderStat) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_FolderStat.Unmarshal(m, b)
-}
-func (m *FolderStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_FolderStat.Marshal(b, m, deterministic)
-}
-func (m *FolderStat) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_FolderStat.Merge(m, src)
-}
-func (m *FolderStat) XXX_Size() int {
-	return xxx_messageInfo_FolderStat.Size(m)
-}
-func (m *FolderStat) XXX_DiscardUnknown() {
-	xxx_messageInfo_FolderStat.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_FolderStat proto.InternalMessageInfo
-
-func (m *FolderStat) GetFolder() string {
-	if m != nil {
-		return m.Folder
-	}
-	return ""
-}
-
-func (m *FolderStat) GetTotal() uint32 {
-	if m != nil {
-		return m.Total
-	}
-	return 0
-}
-
-func (m *FolderStat) GetUnread() uint32 {
-	if m != nil {
-		return m.Unread
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*MailBody)(nil), "common.MailBody")
-	proto.RegisterType((*MailHeader)(nil), "common.MailHeader")
-	proto.RegisterType((*Mail)(nil), "common.Mail")
-	proto.RegisterType((*Attachment)(nil), "common.Attachment")
-	proto.RegisterType((*AttachmentHeader)(nil), "common.AttachmentHeader")
-	proto.RegisterType((*UserInfo)(nil), "common.UserInfo")
-	proto.RegisterType((*Frame)(nil), "common.Frame")
-	proto.RegisterType((*Folder)(nil), "common.Folder")
-	proto.RegisterType((*FolderStat)(nil), "common.FolderStat")
-}
-
-func init() { proto.RegisterFile("gostfix.proto", fileDescriptor_0ab36b6dc6e1dcaa) }
-
-var fileDescriptor_0ab36b6dc6e1dcaa = []byte{
-	// 437 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x53, 0xc1, 0x8e, 0xd3, 0x40,
-	0x0c, 0x55, 0xdb, 0x34, 0xb4, 0x0e, 0x45, 0x5d, 0x0b, 0xa1, 0x08, 0x71, 0xa8, 0x22, 0x0e, 0x15,
-	0x87, 0x0a, 0x0a, 0xa7, 0xbd, 0xc1, 0x61, 0x05, 0x07, 0x38, 0x0c, 0x8b, 0xc4, 0x91, 0xe9, 0x64,
-	0x42, 0x07, 0x92, 0x4c, 0x94, 0x38, 0xd2, 0xf6, 0xc6, 0xa7, 0x23, 0x3b, 0x93, 0x6d, 0x59, 0x89,
-	0x9b, 0x9f, 0xfd, 0xec, 0xf7, 0xec, 0x49, 0x60, 0xf5, 0xd3, 0x77, 0x54, 0xb8, 0xbb, 0x5d, 0xd3,
-	0x7a, 0xf2, 0x18, 0x1b, 0x5f, 0x55, 0xbe, 0xce, 0xfe, 0x4c, 0x60, 0xf1, 0x59, 0xbb, 0xf2, 0x83,
-	0xcf, 0x4f, 0xf8, 0x02, 0x96, 0x4d, 0xa9, 0x5d, 0x7d, 0x6b, 0xef, 0x28, 0x9d, 0x6c, 0x26, 0xdb,
-	0xa5, 0x3a, 0x27, 0xf0, 0x39, 0x2c, 0x5a, 0x67, 0x8e, 0x52, 0x9c, 0x4a, 0xf1, 0x1e, 0xe3, 0x35,
-	0x24, 0x9a, 0x48, 0x9b, 0x63, 0x65, 0x6b, 0xea, 0xd2, 0xd9, 0x66, 0xb6, 0x4d, 0xf6, 0xe9, 0x6e,
-	0x10, 0xd9, 0xbd, 0xbf, 0x2f, 0x7d, 0xb4, 0x3a, 0xb7, 0xad, 0xba, 0x24, 0xb3, 0x05, 0x60, 0x0b,
-	0x43, 0x0d, 0x11, 0xa2, 0xa2, 0xf5, 0x55, 0xd0, 0x97, 0x18, 0x9f, 0xc0, 0x94, 0x7c, 0x10, 0x9d,
-	0x92, 0x67, 0x6c, 0x4c, 0x3a, 0x1b, 0xb0, 0x31, 0xb8, 0x86, 0xd9, 0xc1, 0x98, 0x34, 0x92, 0x04,
-	0x87, 0x3c, 0x25, 0xd7, 0x64, 0xd3, 0xf9, 0x66, 0xb2, 0x45, 0x25, 0x31, 0xa6, 0xf0, 0xa8, 0xeb,
-	0x0f, 0xbf, 0xac, 0xa1, 0x34, 0x16, 0xe6, 0x08, 0xb3, 0xef, 0x10, 0xb1, 0x03, 0x7c, 0x05, 0xf1,
-	0x51, 0x5c, 0x88, 0x7a, 0xb2, 0xc7, 0x71, 0x83, 0xb3, 0x3f, 0x15, 0x18, 0xf8, 0x12, 0xa2, 0x83,
-	0xcf, 0x4f, 0xe2, 0x2a, 0xd9, 0xaf, 0x2f, 0x99, 0x7c, 0x4c, 0x25, 0xd5, 0x4c, 0x01, 0x9c, 0xb7,
-	0xc7, 0xd7, 0x0f, 0xe6, 0xff, 0xff, 0x42, 0xa3, 0xca, 0xb0, 0x87, 0x16, 0x95, 0xc7, 0xb2, 0x87,
-	0xce, 0x7e, 0xc0, 0xfa, 0x21, 0x9f, 0x2f, 0xe2, 0xf2, 0x70, 0xb3, 0xa9, 0xcb, 0xf9, 0xb1, 0x0a,
-	0x57, 0xda, 0x2f, 0xba, 0xb2, 0xe3, 0x63, 0x8d, 0x18, 0x37, 0x90, 0x18, 0x5f, 0x93, 0xad, 0xe9,
-	0xf6, 0xd4, 0xd8, 0x70, 0xc6, 0xcb, 0x54, 0x76, 0x0d, 0x8b, 0x6f, 0x9d, 0x6d, 0x3f, 0xd5, 0x85,
-	0x67, 0x07, 0x7d, 0x17, 0x1c, 0x2f, 0x95, 0xc4, 0x32, 0xbd, 0x2f, 0xcb, 0x7f, 0xa6, 0x07, 0x9c,
-	0xbd, 0x81, 0xf9, 0x4d, 0xcb, 0x32, 0x08, 0x51, 0xf7, 0xdb, 0x35, 0xd2, 0x78, 0xa5, 0x24, 0xc6,
-	0xa7, 0x30, 0x2f, 0x5d, 0xe5, 0x86, 0x0f, 0xe8, 0x4a, 0x0d, 0x20, 0x7b, 0x07, 0xf1, 0x8d, 0x2f,
-	0xc3, 0xba, 0x35, 0x0f, 0x0d, 0x62, 0x1c, 0xe3, 0x33, 0x88, 0x4d, 0xdf, 0x91, 0xaf, 0xa4, 0x69,
-	0xa1, 0x02, 0xe2, 0xd3, 0x0e, 0x5d, 0x5f, 0x49, 0x13, 0xb3, 0x0a, 0x41, 0xa1, 0x37, 0x20, 0x56,
-	0x24, 0x4f, 0xba, 0x94, 0xe6, 0x95, 0x1a, 0x00, 0xb3, 0xfb, 0xba, 0xb5, 0x3a, 0x97, 0xed, 0x57,
-	0x2a, 0xa0, 0x43, 0x2c, 0x7f, 0xc7, 0xdb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xef, 0x23, 0xbe,
-	0x5d, 0x2e, 0x03, 0x00, 0x00,
-}

+ 2 - 2
common/gostfix.proto

@@ -1,5 +1,5 @@
 syntax = "proto3";
-
+option go_package = "./common";
 package common;
 
 message MailBody {
@@ -52,4 +52,4 @@ message FolderStat {
 	string folder = 1;
 	uint32 total = 2;
 	uint32 unread = 3;
-}
+}

+ 5 - 4
config/config.go

@@ -122,10 +122,11 @@ func newConfig() (config *gostfixConfig, err error) {
 		return
 	}
 
-	if !utils.FileExists(mapsList[1] + ".db") {
-		log.Fatalf("Virtual mailbox map %s doesn't exist, postfix is not configured proper way, check %s in %s\n", mapsList[1], PostfixKeyVirtualMailboxMaps, postfixConfigPath)
-		return
-	}
+	// TODO: Trigger initial setup cycle instead of throwing an error
+	// if !utils.FileExists(mapsList[1] + ".db") {
+	// 	log.Fatalf("Virtual mailbox map %s doesn't exist, postfix is not configured proper way, check %s in %s\n", mapsList[1], PostfixKeyVirtualMailboxMaps, postfixConfigPath)
+	// 	return
+	// }
 
 	domains := postfixCfg.Section("").Key(PostfixKeyVirtualMailboxDomains).String()
 	domainsList := strings.Split(domains, " ")

+ 30 - 4
db/db.go

@@ -106,6 +106,30 @@ func NewStorage() (s *Storage, err error) {
 		Options: options.Index().SetUnique(true),
 	}
 
+	collections, err := db.ListCollectionNames(context.Background(), bson.D{})
+
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	createAllEmails := true
+	for _, collection := range collections {
+		if collection == "allEmails" {
+			createAllEmails = false
+		}
+		log.Println(collection)
+	}
+
+	if createAllEmails {
+		unwindStage := bson.D{{"$unwind", bson.D{{"path", "$email"}}}}
+		groupStage := bson.D{{"$group", bson.D{{"_id", "null"}, {"emails", bson.D{{"$addToSet", "$email"}}}}}}
+		pipeline := mongo.Pipeline{unwindStage, groupStage}
+		err = db.CreateView(context.Background(), "allEmails", "emails", pipeline)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+
 	s = &Storage{
 		db:                  db,
 		usersCollection:     db.Collection("users"),
@@ -557,16 +581,18 @@ func (s *Storage) ReadEmailMaps() (map[string]string, error) {
 	mailPath := config.ConfigInstance().VMailboxBase
 
 	mapsFile := config.ConfigInstance().VMailboxMaps
-	if !utils.FileExists(mapsFile) {
-		return nil, errors.New("Could not read virtual mailbox maps")
-	}
 
 	db, err := berkeleydb.NewDB()
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	err = db.Open(config.ConfigInstance().VMailboxMaps, berkeleydb.DbHash, berkeleydb.DbRdOnly)
+	if !utils.FileExists(config.ConfigInstance().VMailboxMaps) {
+		err = db.Open(config.ConfigInstance().VMailboxMaps, berkeleydb.DbHash, berkeleydb.DbCreate)
+	} else {
+		err = db.Open(config.ConfigInstance().VMailboxMaps, berkeleydb.DbHash, berkeleydb.DbRdOnly)
+	}
+
 	if err != nil {
 		return nil, errors.New("Unable to open virtual mailbox maps " + mapsFile + " " + err.Error())
 	}

+ 9 - 8
go.mod

@@ -4,20 +4,21 @@ go 1.14
 
 require (
 	github.com/fsnotify/fsnotify v1.4.9
-	github.com/golang/protobuf v1.4.1
-	github.com/google/uuid v1.1.1
+	github.com/google/uuid v1.1.2
 	github.com/gorilla/sessions v1.2.0
 	github.com/gorilla/websocket v1.4.2
 	github.com/jhillyerd/enmime v0.8.1
 	github.com/jsimonetti/berkeleydb v0.0.0-20170815141343-5cde5eaaf78c // indirect
-	github.com/pkg/profile v1.5.0
+	github.com/pkg/profile v1.6.0
 	github.com/semlanik/berkeleydb v0.0.0-20200324082802-7b28da5446c0
 	github.com/smartystreets/goconvey v1.6.4 // indirect
-	github.com/stretchr/testify v1.4.0 // indirect
-	go.mongodb.org/mongo-driver v1.3.5
-	golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586
-	golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
-	google.golang.org/protobuf v1.25.0 // indirect
+	github.com/stretchr/testify v1.7.0 // indirect
+	go.mongodb.org/mongo-driver v1.5.1
+	golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
+	golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 // indirect
+	golang.org/x/sys v0.0.0-20220422013727-9388b58f7150
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	google.golang.org/protobuf v1.28.0
 	gopkg.in/go-ini/ini.v1 v1.57.0
 	gopkg.in/ini.v1 v1.57.0 // indirect
 )

+ 56 - 87
go.sum

@@ -1,16 +1,14 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
+github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
 github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
 github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
@@ -41,28 +39,14 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 h1:aBzukfDxQlCTVS0NBUjI5YA3iVeaZ9Tb5PxNrrIP1xs=
 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
@@ -76,6 +60,10 @@ github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 h1:jTkyeF7NZ5o
 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
 github.com/jhillyerd/enmime v0.8.1 h1:Kz4xj3sJJ4Ju8e+w/7v9H4Matv5ijPgv7UkhPf+C15I=
 github.com/jhillyerd/enmime v0.8.1/go.mod h1:MBHs3ugk03NGjMM6PuRynlKf+HA5eSillZ+TRCm73AE=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/jsimonetti/berkeleydb v0.0.0-20170815141343-5cde5eaaf78c h1:/5ja7kk4aMhLJiRTtOhbPYLb9Y95VlqFiRTAoIhrHI4=
 github.com/jsimonetti/berkeleydb v0.0.0-20170815141343-5cde5eaaf78c/go.mod h1:MzZzsYRTOJXLM04/edhWq3Y89ktkIWH0OcenhMCSHfs=
@@ -99,15 +87,15 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
 github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug=
-github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
+github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -129,88 +117,69 @@ github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02n
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
-github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
-github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
-go.mongodb.org/mongo-driver v1.3.5 h1:S0ZOruh4YGHjD7JoN7mIsTrNjnQbOjrmgrx6l6pZN7I=
-go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW6TgOeJ5c=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
+github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
+github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
+go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 h1:yssD99+7tqHWO5Gwh81phT+67hg+KttniBr6UnEXOY8=
+golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
+golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -219,7 +188,7 @@ gopkg.in/go-ini/ini.v1 v1.57.0 h1:e9cP3G5H9zMIwvQnUDbnD7k5SFuSbrPWdSAV8VHKxX8=
 gopkg.in/go-ini/ini.v1 v1.57.0/go.mod h1:M74/hG4RTwbkZyTEZ9iQwM4v6dFD4u6QBjoqT/pM8Kg=
 gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
 gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 1 - 1
main.go

@@ -31,7 +31,7 @@ import (
 	sasl "git.semlanik.org/semlanik/gostfix/sasl"
 	scanner "git.semlanik.org/semlanik/gostfix/scanner"
 	web "git.semlanik.org/semlanik/gostfix/web"
-	profile "github.com/pkg/profile"
+	"github.com/pkg/profile"
 )
 
 type GofixEngine struct {

+ 3 - 2
scanner/mailscanner.go

@@ -49,14 +49,15 @@ type MailScanner struct {
 }
 
 func NewMailScanner() (ms *MailScanner) {
+	log.Print("test2")
 	watcher, err := fsnotify.NewWatcher()
 	if err != nil {
 		log.Fatal(err)
 		return
 	}
-
+	log.Print("test2")
 	storage, err := db.NewStorage()
-
+	log.Print("test3")
 	if err != nil {
 		log.Fatal(err)
 		return

+ 1 - 1
views

@@ -1 +1 @@
-db.createView("allEmails", "emails", [{$unwind:"$email"},{$group: {_id: null, emails: {$addToSet: "$email"}}}]
+db.createView("allEmails", "emails", [{$unwind:"$email"},{$group: {_id: null, emails: {$addToSet: "$email"}}}])