messager

package
v2.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package messager package using injected engine.Store to save and load messages. It does all encryption/decryption and hashing. Store used as a dump storage only. Passed (from user) pin used as a part of encryption key for data and delegated to crypt.Crypt. Pins not saved directly, but hashed with bcrypt.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadPin         = errors.New("wrong pin")
	ErrBadPinAttempt  = errors.New("wrong pin attempt")
	ErrCrypto         = errors.New("crypto error")
	ErrInternal       = errors.New("internal error")
	ErrExpired        = errors.New("message expired")
	ErrDuration       = errors.New("bad duration")
	ErrFileTooLarge   = errors.New("file too large")
	ErrBadFileName    = errors.New("invalid file name")
	ErrBadContentType = errors.New("invalid content type")
)

Errors

Functions

func IsFileMessage

func IsFileMessage(data []byte) bool

IsFileMessage checks if message data has file prefix (works on raw stored data)

func MakeSignKey

func MakeSignKey(signKey string, pinSize int) (result string)

MakeSignKey creates 32-pin bytes signKey for AES256

func ParseFileHeader

func ParseFileHeader(data []byte) (filename, contentType string, dataStart int)

ParseFileHeader extracts filename, content-type, and data start position from file message. Returns empty strings and -1 if not a valid file message.

Types

type Crypt

type Crypt struct {
	Key string
}

Crypt data with a global key + pin. It provides NaCl secretbox encryption (XSalsa20-Poly1305) for data needed to prevent storing it in naked form even in_memory storage.

func (Crypt) Decrypt

func (c Crypt) Decrypt(req Request) ([]byte, error)

Decrypt decrypts base64-encoded data with secretbox

func (Crypt) Encrypt

func (c Crypt) Encrypt(req Request) ([]byte, error)

Encrypt encrypts data with secretbox and returns base64-encoded result

type Crypter

type Crypter interface {
	Encrypt(req Request) (result []byte, err error)
	Decrypt(req Request) (result []byte, err error)
}

Crypter interface wraps crypt methods

type CrypterMock

type CrypterMock struct {
	// DecryptFunc mocks the Decrypt method.
	DecryptFunc func(req Request) ([]byte, error)

	// EncryptFunc mocks the Encrypt method.
	EncryptFunc func(req Request) ([]byte, error)
	// contains filtered or unexported fields
}

CrypterMock is a mock implementation of Crypter.

func TestSomethingThatUsesCrypter(t *testing.T) {

	// make and configure a mocked Crypter
	mockedCrypter := &CrypterMock{
		DecryptFunc: func(req Request) ([]byte, error) {
			panic("mock out the Decrypt method")
		},
		EncryptFunc: func(req Request) ([]byte, error) {
			panic("mock out the Encrypt method")
		},
	}

	// use mockedCrypter in code that requires Crypter
	// and then make assertions.

}

func (*CrypterMock) Decrypt

func (mock *CrypterMock) Decrypt(req Request) ([]byte, error)

Decrypt calls DecryptFunc.

func (*CrypterMock) DecryptCalls

func (mock *CrypterMock) DecryptCalls() []struct {
	Req Request
}

DecryptCalls gets all the calls that were made to Decrypt. Check the length with:

len(mockedCrypter.DecryptCalls())

func (*CrypterMock) Encrypt

func (mock *CrypterMock) Encrypt(req Request) ([]byte, error)

Encrypt calls EncryptFunc.

func (*CrypterMock) EncryptCalls

func (mock *CrypterMock) EncryptCalls() []struct {
	Req Request
}

EncryptCalls gets all the calls that were made to Encrypt. Check the length with:

len(mockedCrypter.EncryptCalls())

type Engine

type Engine interface {
	Save(ctx context.Context, msg *store.Message) (err error)
	Load(ctx context.Context, key string) (result *store.Message, err error)
	IncErr(ctx context.Context, key string) (count int, err error)
	Remove(ctx context.Context, key string) (err error)
	Close() error
}

Engine defines interface to save, load, remove and inc errors count for messages

type EngineMock

type EngineMock struct {
	// CloseFunc mocks the Close method.
	CloseFunc func() error

	// IncErrFunc mocks the IncErr method.
	IncErrFunc func(ctx context.Context, key string) (int, error)

	// LoadFunc mocks the Load method.
	LoadFunc func(ctx context.Context, key string) (*store.Message, error)

	// RemoveFunc mocks the Remove method.
	RemoveFunc func(ctx context.Context, key string) error

	// SaveFunc mocks the Save method.
	SaveFunc func(ctx context.Context, msg *store.Message) error
	// contains filtered or unexported fields
}

EngineMock is a mock implementation of Engine.

func TestSomethingThatUsesEngine(t *testing.T) {

	// make and configure a mocked Engine
	mockedEngine := &EngineMock{
		CloseFunc: func() error {
			panic("mock out the Close method")
		},
		IncErrFunc: func(ctx context.Context, key string) (int, error) {
			panic("mock out the IncErr method")
		},
		LoadFunc: func(ctx context.Context, key string) (*store.Message, error) {
			panic("mock out the Load method")
		},
		RemoveFunc: func(ctx context.Context, key string) error {
			panic("mock out the Remove method")
		},
		SaveFunc: func(ctx context.Context, msg *store.Message) error {
			panic("mock out the Save method")
		},
	}

	// use mockedEngine in code that requires Engine
	// and then make assertions.

}

func (*EngineMock) Close

func (mock *EngineMock) Close() error

Close calls CloseFunc.

func (*EngineMock) CloseCalls

func (mock *EngineMock) CloseCalls() []struct {
}

CloseCalls gets all the calls that were made to Close. Check the length with:

len(mockedEngine.CloseCalls())

func (*EngineMock) IncErr

func (mock *EngineMock) IncErr(ctx context.Context, key string) (int, error)

IncErr calls IncErrFunc.

func (*EngineMock) IncErrCalls

func (mock *EngineMock) IncErrCalls() []struct {
	Ctx context.Context
	Key string
}

IncErrCalls gets all the calls that were made to IncErr. Check the length with:

len(mockedEngine.IncErrCalls())

func (*EngineMock) Load

func (mock *EngineMock) Load(ctx context.Context, key string) (*store.Message, error)

Load calls LoadFunc.

func (*EngineMock) LoadCalls

func (mock *EngineMock) LoadCalls() []struct {
	Ctx context.Context
	Key string
}

LoadCalls gets all the calls that were made to Load. Check the length with:

len(mockedEngine.LoadCalls())

func (*EngineMock) Remove

func (mock *EngineMock) Remove(ctx context.Context, key string) error

Remove calls RemoveFunc.

func (*EngineMock) RemoveCalls

func (mock *EngineMock) RemoveCalls() []struct {
	Ctx context.Context
	Key string
}

RemoveCalls gets all the calls that were made to Remove. Check the length with:

len(mockedEngine.RemoveCalls())

func (*EngineMock) Save

func (mock *EngineMock) Save(ctx context.Context, msg *store.Message) error

Save calls SaveFunc.

func (*EngineMock) SaveCalls

func (mock *EngineMock) SaveCalls() []struct {
	Ctx context.Context
	Msg *store.Message
}

SaveCalls gets all the calls that were made to Save. Check the length with:

len(mockedEngine.SaveCalls())

type FileRequest

type FileRequest struct {
	Duration    time.Duration
	Pin         string
	FileName    string
	ContentType string
	Data        []byte
}

FileRequest contains data for file message creation

type MessageProc

type MessageProc struct {
	Params
	// contains filtered or unexported fields
}

MessageProc creates and save messages and retrieve per key

func New

func New(engine Engine, crypter Crypter, params Params) *MessageProc

New makes MessageProc with the engine and crypt

func (MessageProc) HasPin added in v2.2.0

func (p MessageProc) HasPin(ctx context.Context, key string) (bool, error)

HasPin checks if a message requires PIN for access. Returns true if message has a PIN hash, false if PIN-less. Returns error if message doesn't exist.

func (MessageProc) IsFile

func (p MessageProc) IsFile(ctx context.Context, key string) bool

IsFile checks if a message with given key is a file message (without decrypting). Returns false if message doesn't exist, is not a file, or is client-encrypted. For client-encrypted messages, server can't inspect the opaque blob.

func (MessageProc) LoadMessage

func (p MessageProc) LoadMessage(ctx context.Context, key, pin string) (msg *store.Message, err error)

LoadMessage gets from engine, verifies Message with pin and decrypts content. It also removes accessed messages and invalidate them on multiple wrong pins. Message decrypted by this function will be returned naked to consumer.

func (MessageProc) MakeFileMessage

func (p MessageProc) MakeFileMessage(ctx context.Context, req FileRequest) (result *store.Message, err error)

MakeFileMessage creates a message from file data with unencrypted prefix for metadata. Format: !!FILE!!filename!!content-type!!\n<encrypted binary> This function is for API file uploads only (server-side encryption). UI file uploads use client-side encryption via MakeMessage with the encrypted blob.

func (MessageProc) MakeMessage

func (p MessageProc) MakeMessage(ctx context.Context, req MsgReq) (result *store.Message, err error)

MakeMessage creates and saves a message from the request. If ClientEnc is true, data is stored as-is (client handles encryption). If ClientEnc is false, data is encrypted server-side with pin.

type MsgReq added in v2.1.0

type MsgReq struct {
	Duration      time.Duration
	Pin           string
	Message       string
	ClientEnc     bool // true for client-side encryption (UI), false for server-side (API)
	AllowEmptyPin bool // true to allow creating messages without PIN protection
}

MsgReq contains data for message creation

type Params

type Params struct {
	MaxDuration    time.Duration
	MaxPinAttempts int
	MaxFileSize    int64
}

Params to customize limits

type Request

type Request struct {
	Pin  string
	Data []byte
}

Request for both Encrypt and Decrypt

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL