README

alps

GoDoc builds.sr.ht status

A simple and extensible webmail.

Usage

Assuming SRV DNS records are properly set up (see RFC 6186):

go run ./cmd/alps example.org

To manually specify upstream servers:

go run ./cmd/alps imaps://mail.example.org:993 smtps://mail.example.org:465

Add -theme alps to use the alps theme. See docs/cli.md for more information.

When developing themes and plugins, the script contrib/hotreload.sh can be used to automatically reload alps on file changes.

Contributing

Send patches on the mailing list, report bugs on the issue tracker.

License

MIT

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const PluginDir = "plugins"

    PluginDir is the path to the plugins directory.

    Variables

    View Source
    var (
    	ErrSessionExpired      = errors.New("session expired")
    	ErrAttachmentCacheSize = errors.New("Attachments on session exceed maximum file size")
    )
    View Source
    var ErrNoStoreEntry = fmt.Errorf("alps: no such entry in store")

      ErrNoStoreEntry is returned by Store.Get when the entry doesn't exist.

      Functions

      func RegisterPluginLoader

      func RegisterPluginLoader(f PluginLoaderFunc)

        RegisterPluginLoader registers a plugin loader. The loader will be called on server start-up and reload.

        Types

        type Attachment

        type Attachment struct {
        	File *multipart.FileHeader
        	Form *multipart.Form
        }

        type AuthError

        type AuthError struct {
        	// contains filtered or unexported fields
        }

          AuthError wraps an authentication error.

          func (AuthError) Error

          func (err AuthError) Error() string

          type BaseRenderData

          type BaseRenderData struct {
          	GlobalData GlobalRenderData
          	// additional plugin-specific data
          	Extra map[string]interface{}
          }

            BaseRenderData is the base type for templates. It should be extended with additional template-specific fields:

            type MyRenderData struct {
                BaseRenderData
                // add additional fields here
            }
            

            func NewBaseRenderData

            func NewBaseRenderData(ectx echo.Context) *BaseRenderData

              NewBaseRenderData initializes a new BaseRenderData.

              It can be used by routes to pre-fill the base data:

              type MyRenderData struct {
                  BaseRenderData
                  // add additional fields here
              }
              
              data := &MyRenderData{
                  BaseRenderData: *alps.NewBaseRenderData(ctx),
                  // other fields...
              }
              

              func (*BaseRenderData) Global

              func (brd *BaseRenderData) Global() *GlobalRenderData

                Global implements RenderData.

                func (*BaseRenderData) WithTitle

                func (brd *BaseRenderData) WithTitle(title string) *BaseRenderData

                type Context

                type Context struct {
                	echo.Context
                	Server  *Server
                	Session *Session // nil if user isn't logged in
                }

                  Context is the context used by HTTP handlers.

                  Use a type assertion to get it from a echo.Context:

                  ctx := ectx.(*alps.Context)
                  

                  func (*Context) GetLoginToken

                  func (ctx *Context) GetLoginToken() (string, string)

                  func (*Context) SetLoginToken

                  func (ctx *Context) SetLoginToken(username, password string)

                  func (*Context) SetSession

                  func (ctx *Context) SetSession(s *Session)

                    SetSession sets a cookie for the provided session. Passing a nil session unsets the cookie.

                    type DialIMAPFunc

                    type DialIMAPFunc func() (*imapclient.Client, error)

                      DialIMAPFunc connects to the upstream IMAP server.

                      type DialSMTPFunc

                      type DialSMTPFunc func() (*smtp.Client, error)

                        DialSMTPFunc connects to the upstream SMTP server.

                        type GlobalRenderData

                        type GlobalRenderData struct {
                        	Path []string
                        	URL  *url.URL
                        
                        	LoggedIn bool
                        
                        	// if logged in
                        	Username string
                        
                        	Title string
                        
                        	HavePlugin func(name string) bool
                        
                        	Notice string
                        
                        	// additional plugin-specific data
                        	Extra map[string]interface{}
                        }

                          GlobalRenderData contains data available in all templates.

                          type GoPlugin

                          type GoPlugin struct {
                          	Name string
                          	// contains filtered or unexported fields
                          }

                            GoPlugin is a helper to create Go plugins.

                            Use this struct to define your plugin, then call RegisterPluginLoader:

                            p := GoPlugin{Name: "my-plugin"}
                            // Define routes, template functions, etc
                            alps.RegisterPluginLoader(p.Loader())
                            

                            func (*GoPlugin) AddRoute

                            func (p *GoPlugin) AddRoute(method, path string, handler HandlerFunc)

                              AddRoute registers a new HTTP route.

                              func (*GoPlugin) DELETE

                              func (p *GoPlugin) DELETE(path string, handler HandlerFunc)

                              func (*GoPlugin) GET

                              func (p *GoPlugin) GET(path string, handler HandlerFunc)

                              func (*GoPlugin) Inject

                              func (p *GoPlugin) Inject(name string, f InjectFunc)

                                Inject registers a function to execute prior to rendering a template. The special name "*" matches any template.

                                func (*GoPlugin) Loader

                                func (p *GoPlugin) Loader() PluginLoaderFunc

                                  Loader returns a loader function for this plugin.

                                  func (*GoPlugin) POST

                                  func (p *GoPlugin) POST(path string, handler HandlerFunc)

                                  func (*GoPlugin) PUT

                                  func (p *GoPlugin) PUT(path string, handler HandlerFunc)

                                  func (*GoPlugin) Plugin

                                  func (p *GoPlugin) Plugin() Plugin

                                    Plugin returns an object implementing Plugin.

                                    func (*GoPlugin) TemplateFuncs

                                    func (p *GoPlugin) TemplateFuncs(funcs template.FuncMap)

                                      TemplateFuncs registers new template functions.

                                      type HandlerFunc

                                      type HandlerFunc func(*Context) error

                                        HandlerFunc is a function serving HTTP requests.

                                        type InjectFunc

                                        type InjectFunc func(ctx *Context, data RenderData) error

                                          InjectFunc is a function that injects data prior to rendering a template.

                                          type NoUpstreamError

                                          type NoUpstreamError struct {
                                          	// contains filtered or unexported fields
                                          }

                                          func (*NoUpstreamError) Error

                                          func (err *NoUpstreamError) Error() string

                                          type Options

                                          type Options struct {
                                          	Upstreams []string
                                          	Theme     string
                                          	Debug     bool
                                          	LoginKey  *fernet.Key
                                          }

                                          type Plugin

                                          type Plugin interface {
                                          	// Name should return the plugin name.
                                          	Name() string
                                          	// LoadTemplate populates t with the plugin's functions and templates.
                                          	LoadTemplate(t *template.Template) error
                                          	// SetRoutes populates group with the plugin's routes.
                                          	SetRoutes(group *echo.Group)
                                          	// Inject is called prior to rendering a template. It can extend the
                                          	// template data by setting new items in the Extra map.
                                          	Inject(ctx *Context, name string, data RenderData) error
                                          	// Close is called when the plugin is unloaded.
                                          	Close() error
                                          }

                                            Plugin extends alps with additional functionality.

                                            type PluginLoaderFunc

                                            type PluginLoaderFunc func(*Server) ([]Plugin, error)

                                              PluginLoaderFunc loads plugins for the provided server.

                                              type RenderData

                                              type RenderData interface {
                                              	// GlobalData returns a pointer to the global render data.
                                              	Global() *GlobalRenderData
                                              }

                                                RenderData is implemented by template data structs. It can be used to inject additional data to all templates.

                                                type Server

                                                type Server struct {
                                                	Sessions *SessionManager
                                                	Options  *Options
                                                	// contains filtered or unexported fields
                                                }

                                                  Server holds all the alps server state.

                                                  func New

                                                  func New(e *echo.Echo, options *Options) (*Server, error)

                                                    New creates a new server.

                                                    func (*Server) Close

                                                    func (s *Server) Close()

                                                    func (*Server) Logger

                                                    func (s *Server) Logger() echo.Logger

                                                      Logger returns this server's logger.

                                                      func (*Server) Reload

                                                      func (s *Server) Reload() error

                                                        Reload loads Lua plugins and templates from disk.

                                                        func (*Server) Upstream

                                                        func (s *Server) Upstream(schemes ...string) (*url.URL, error)

                                                          Upstream retrieves the configured upstream server URL for the provided schemes. If no configured upstream server matches, a *NoUpstreamError is returned. An empty URL.Scheme means that the caller needs to perform auto-discovery with URL.Host.

                                                          type Session

                                                          type Session struct {
                                                          	// contains filtered or unexported fields
                                                          }

                                                            Session is an active user session. It may also hold an IMAP connection.

                                                            The session's password is not available to plugins. Plugins should use the session helpers to authenticate outgoing connections, for instance DoSMTP.

                                                            func (*Session) Close

                                                            func (s *Session) Close()

                                                              Close destroys the session. This can be used to log the user out.

                                                              func (*Session) DoIMAP

                                                              func (s *Session) DoIMAP(f func(*imapclient.Client) error) error

                                                                DoIMAP executes an IMAP operation on this session. The IMAP client can only be used from inside f.

                                                                func (*Session) DoSMTP

                                                                func (s *Session) DoSMTP(f func(*smtp.Client) error) error

                                                                  DoSMTP executes an SMTP operation on this session. The SMTP client can only be used from inside f.

                                                                  func (*Session) PopAttachment

                                                                  func (s *Session) PopAttachment(uuid string) *Attachment

                                                                    Removes an attachment from the session. Returns nil if there was no such attachment.

                                                                    func (*Session) PopNotice

                                                                    func (s *Session) PopNotice() string

                                                                    func (*Session) PutAttachment

                                                                    func (s *Session) PutAttachment(in *multipart.FileHeader,
                                                                    	form *multipart.Form) (string, error)

                                                                      Puts an attachment and returns a generated UUID

                                                                      func (*Session) PutNotice

                                                                      func (s *Session) PutNotice(n string)

                                                                      func (*Session) SetHTTPBasicAuth

                                                                      func (s *Session) SetHTTPBasicAuth(req *http.Request)

                                                                        SetHTTPBasicAuth adds an Authorization header field to the request with this session's credentials.

                                                                        func (*Session) Store

                                                                        func (s *Session) Store() Store

                                                                          Store returns a store suitable for storing persistent user data.

                                                                          func (*Session) Username

                                                                          func (s *Session) Username() string

                                                                            Username returns the session's username.

                                                                            type SessionManager

                                                                            type SessionManager struct {
                                                                            	// contains filtered or unexported fields
                                                                            }

                                                                              SessionManager keeps track of active sessions. It connects and re-connects to the upstream IMAP server as necessary. It prunes expired sessions.

                                                                              func (*SessionManager) Close

                                                                              func (sm *SessionManager) Close()

                                                                              func (*SessionManager) Put

                                                                              func (sm *SessionManager) Put(username, password string) (*Session, error)

                                                                                Put connects to the IMAP server and creates a new session. If authentication fails, the error will be of type AuthError.

                                                                                type Store

                                                                                type Store interface {
                                                                                	Get(key string, out interface{}) error
                                                                                	Put(key string, v interface{}) error
                                                                                }

                                                                                  Store allows storing per-user persistent data.

                                                                                  Store shouldn't be used from inside Session.DoIMAP.

                                                                                  Directories

                                                                                  Path Synopsis
                                                                                  cmd
                                                                                  docs
                                                                                  example-go-plugin
                                                                                  Package exampleplugin is an example Go plugin for alps.
                                                                                  Package exampleplugin is an example Go plugin for alps.
                                                                                  plugins
                                                                                  lua