@@ -70,9 +70,6 @@ func main() { | |||||
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ | e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ | ||||
Format: "${time_rfc3339} method=${method}, uri=${uri}, status=${status}\n", | Format: "${time_rfc3339} method=${method}, uri=${uri}, status=${status}\n", | ||||
})) | })) | ||||
} | |||||
if options.Debug { | |||||
e.Logger.SetLevel(log.DEBUG) | e.Logger.SetLevel(log.DEBUG) | ||||
} | } | ||||
@@ -118,7 +118,7 @@ func newIMAPBaseRenderData(ctx *alps.Context, | |||||
} | } | ||||
if mboxName != "" { | if mboxName != "" { | ||||
if active, err = getMailboxStatus(c, mboxName); err != nil { | if active, err = getMailboxStatus(c, mboxName); err != nil { | ||||
return err | |||||
return echo.NewHTTPError(http.StatusNotFound, err) | |||||
} | } | ||||
} | } | ||||
if mboxName == "INBOX" { | if mboxName == "INBOX" { | ||||
@@ -70,14 +70,19 @@ type RenderData interface { | |||||
// BaseRenderData: *alps.NewBaseRenderData(ctx), | // BaseRenderData: *alps.NewBaseRenderData(ctx), | ||||
// // other fields... | // // other fields... | ||||
// } | // } | ||||
func NewBaseRenderData(ctx *Context) *BaseRenderData { | |||||
func NewBaseRenderData(ectx echo.Context) *BaseRenderData { | |||||
ctx, isactx := ectx.(*Context) | |||||
global := GlobalRenderData{ | global := GlobalRenderData{ | ||||
Extra: make(map[string]interface{}), | Extra: make(map[string]interface{}), | ||||
Path: strings.Split(ctx.Request().URL.Path, "/")[1:], | |||||
Path: strings.Split(ectx.Request().URL.Path, "/")[1:], | |||||
Title: "Webmail", | Title: "Webmail", | ||||
URL: ctx.Request().URL, | |||||
URL: ectx.Request().URL, | |||||
HavePlugin: func(name string) bool { | HavePlugin: func(name string) bool { | ||||
if !isactx { | |||||
return false | |||||
} | |||||
for _, plugin := range ctx.Server.plugins { | for _, plugin := range ctx.Server.plugins { | ||||
if plugin.Name() == name { | if plugin.Name() == name { | ||||
return true | return true | ||||
@@ -87,7 +92,7 @@ func NewBaseRenderData(ctx *Context) *BaseRenderData { | |||||
}, | }, | ||||
} | } | ||||
if ctx.Session != nil { | |||||
if isactx && ctx.Session != nil { | |||||
global.LoggedIn = true | global.LoggedIn = true | ||||
global.Username = ctx.Session.username | global.Username = ctx.Session.username | ||||
} | } | ||||
@@ -382,15 +382,31 @@ func New(e *echo.Echo, options *Options) (*Server, error) { | |||||
return nil, err | return nil, err | ||||
} | } | ||||
e.HTTPErrorHandler = func(err error, c echo.Context) { | |||||
e.HTTPErrorHandler = func(err error, ctx echo.Context) { | |||||
code := http.StatusInternalServerError | code := http.StatusInternalServerError | ||||
if he, ok := err.(*echo.HTTPError); ok { | if he, ok := err.(*echo.HTTPError); ok { | ||||
code = he.Code | code = he.Code | ||||
} else { | |||||
c.Logger().Error(err) | |||||
} | } | ||||
// TODO: hide internal errors | |||||
c.String(code, err.Error()) | |||||
type ErrorRenderData struct { | |||||
BaseRenderData | |||||
Code int | |||||
Err error | |||||
Status string | |||||
} | |||||
rdata := ErrorRenderData{ | |||||
BaseRenderData: *NewBaseRenderData(ctx), | |||||
Err: err, | |||||
Code: code, | |||||
Status: http.StatusText(code), | |||||
} | |||||
if err := ctx.Render(code, "error.html", &rdata); err != nil { | |||||
ctx.Logger().Error(fmt.Errorf( | |||||
"Error occured rendering error page: %w. How meta.", err)) | |||||
} | |||||
ctx.Logger().Error(err) | |||||
} | } | ||||
e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { | e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { | ||||
@@ -123,8 +123,19 @@ footer { text-align: right; } | |||||
.actions { padding: 0.5rem; } | .actions { padding: 0.5rem; } | ||||
.container { flex: 1 auto; display: flex; flex-direction: column; flex-wrap: nowrap; min-width: 0; } | |||||
.container { | |||||
flex: 1 auto; | |||||
display: flex; | |||||
flex-direction: column; | |||||
flex-wrap: nowrap; | |||||
min-width: 0; | |||||
} | |||||
.container.error { | |||||
max-width: 800px; | |||||
margin: 0 auto; | |||||
padding: 1rem 0; | |||||
} | |||||
aside { flex: 0 0 180px; } | aside { flex: 0 0 180px; } | ||||
@@ -0,0 +1,14 @@ | |||||
{{template "head.html" .}} | |||||
<div class="page-wrap"> | |||||
<div class="container error"> | |||||
<h1>{{.Code}}: {{.Status}}</h1> | |||||
<p> | |||||
An error occured. You can try | |||||
<a href="/">returning to your inbox</a>, | |||||
or contact support. | |||||
</p> | |||||
</div> | |||||
</div> | |||||
{{template "foot.html"}} |
@@ -22,10 +22,12 @@ | |||||
{{ end }} | {{ end }} | ||||
>Contacts</a> | >Contacts</a> | ||||
{{ end }} | {{ end }} | ||||
{{ if .GlobalData.LoggedIn }} | |||||
<div> | <div> | ||||
<span>{{ .GlobalData.Username }}</span> | <span>{{ .GlobalData.Username }}</span> | ||||
<a href="/settings">Settings</a> | <a href="/settings">Settings</a> | ||||
<a href="/logout">Sign Out</a> | <a href="/logout">Sign Out</a> | ||||
</div> | </div> | ||||
{{ end }} | |||||
</nav> | </nav> | ||||
</header> | </header> |