mirror of
https://github.com/volatiletech/authboss.git
synced 2025-01-10 04:17:59 +02:00
Add ability to override mail root
- Add config option for MailRoot - Make confirm and recover use MailRoot if present, otherwise assemble URL like normal.
This commit is contained in:
parent
13e6714c87
commit
79d1893bdc
@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
- Add Config option to defaults.HTTPRedirector to allow it to coerce redirect
|
||||
response codes to http.StatusOK to help make more regular APIs.
|
||||
- Add Config option for MailRoot. This is a URL that overrides the typical
|
||||
URL building using Root/MountPath that recover and confirm do to enable
|
||||
creating mail links to a different location than where the API is hosted.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -11,6 +11,7 @@ type Config struct {
|
||||
Paths struct {
|
||||
// Mount is the path to mount authboss's routes at (eg /auth).
|
||||
Mount string
|
||||
|
||||
// NotAuthorized is the default URL to kick users back to when
|
||||
// they attempt an action that requires them to be logged in and they're not auth'd
|
||||
NotAuthorized string
|
||||
@ -99,6 +100,13 @@ type Config struct {
|
||||
}
|
||||
|
||||
Mail struct {
|
||||
// RootURL is a full path to an application that is hosting a front-end
|
||||
// Typically using a combination of Paths.RootURL and Paths.Mount
|
||||
// MailRoot will be assembled if not set.
|
||||
// Typically looks something like: https://our-front-end.com/authenication
|
||||
// No trailing slash
|
||||
RootURL string
|
||||
|
||||
// From is the email address authboss e-mails come from.
|
||||
From string
|
||||
// FromName is the name authboss e-mails come from.
|
||||
|
@ -143,8 +143,7 @@ var goConfirmEmail = func(c *Confirm, ctx context.Context, to, token string) {
|
||||
func (c *Confirm) SendConfirmEmail(ctx context.Context, to, token string) {
|
||||
logger := c.Authboss.Logger(ctx)
|
||||
|
||||
p := path.Join(c.Config.Paths.Mount, "confirm")
|
||||
url := fmt.Sprintf("%s%s?%s=%s", c.Paths.RootURL, p, url.QueryEscape(FormValueConfirm), url.QueryEscape(token))
|
||||
mailURL := c.mailURL(token)
|
||||
|
||||
email := authboss.Email{
|
||||
To: []string{to},
|
||||
@ -156,7 +155,7 @@ func (c *Confirm) SendConfirmEmail(ctx context.Context, to, token string) {
|
||||
logger.Infof("sending confirm e-mail to: %s", to)
|
||||
|
||||
ro := authboss.EmailResponseOptions{
|
||||
Data: authboss.NewHTMLData(DataConfirmURL, url),
|
||||
Data: authboss.NewHTMLData(DataConfirmURL, mailURL),
|
||||
HTMLTemplate: EmailConfirmHTML,
|
||||
TextTemplate: EmailConfirmTxt,
|
||||
}
|
||||
@ -234,6 +233,17 @@ func (c *Confirm) Get(w http.ResponseWriter, r *http.Request) error {
|
||||
return c.Authboss.Config.Core.Redirector.Redirect(w, r, ro)
|
||||
}
|
||||
|
||||
func (c *Confirm) mailURL(token string) string {
|
||||
query := url.Values{FormValueConfirm: []string{token}}
|
||||
|
||||
if len(c.Config.Mail.RootURL) != 0 {
|
||||
return fmt.Sprintf("%s?%s", c.Config.Mail.RootURL+"/confirm", query.Encode())
|
||||
}
|
||||
|
||||
p := path.Join(c.Config.Paths.Mount, "confirm")
|
||||
return fmt.Sprintf("%s%s?%s", c.Config.Paths.RootURL, p, query.Encode())
|
||||
}
|
||||
|
||||
func (c *Confirm) invalidToken(w http.ResponseWriter, r *http.Request) error {
|
||||
ro := authboss.RedirectOptions{
|
||||
Code: http.StatusTemporaryRedirect,
|
||||
|
@ -365,6 +365,26 @@ func TestMiddlewareDisallow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMailURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
h := testSetup()
|
||||
h.ab.Config.Paths.RootURL = "https://api.test.com:6343"
|
||||
h.ab.Config.Paths.Mount = "/v1/auth"
|
||||
|
||||
want := "https://api.test.com:6343/v1/auth/confirm?cnf=abc"
|
||||
if got := h.confirm.mailURL("abc"); got != want {
|
||||
t.Error("want:", want, "got:", got)
|
||||
}
|
||||
|
||||
h.ab.Config.Mail.RootURL = "https://test.com:3333/testauth"
|
||||
|
||||
want = "https://test.com:3333/testauth/confirm?cnf=abc"
|
||||
if got := h.confirm.mailURL("abc"); got != want {
|
||||
t.Error("want:", want, "got:", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRecoverCreds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -131,9 +131,8 @@ var goRecoverEmail = func(r *Recover, ctx context.Context, to, encodedToken stri
|
||||
// in an escaped URL to the templates.
|
||||
func (r *Recover) SendRecoverEmail(ctx context.Context, to, encodedToken string) {
|
||||
logger := r.Authboss.Logger(ctx)
|
||||
p := path.Join(r.Authboss.Config.Paths.Mount, "recover/end")
|
||||
query := url.Values{FormValueToken: []string{encodedToken}}
|
||||
url := fmt.Sprintf("%s%s?%s", r.Authboss.Config.Paths.RootURL, p, query.Encode())
|
||||
|
||||
mailURL := r.mailURL(encodedToken)
|
||||
|
||||
email := authboss.Email{
|
||||
To: []string{to},
|
||||
@ -146,7 +145,7 @@ func (r *Recover) SendRecoverEmail(ctx context.Context, to, encodedToken string)
|
||||
HTMLTemplate: EmailRecoverHTML,
|
||||
TextTemplate: EmailRecoverTxt,
|
||||
Data: authboss.HTMLData{
|
||||
DataRecoverURL: url,
|
||||
DataRecoverURL: mailURL,
|
||||
},
|
||||
}
|
||||
|
||||
@ -271,6 +270,17 @@ func (r *Recover) invalidToken(page string, w http.ResponseWriter, req *http.Req
|
||||
return r.Authboss.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverEnd, data)
|
||||
}
|
||||
|
||||
func (r *Recover) mailURL(token string) string {
|
||||
query := url.Values{FormValueToken: []string{token}}
|
||||
|
||||
if len(r.Config.Mail.RootURL) != 0 {
|
||||
return fmt.Sprintf("%s?%s", r.Config.Mail.RootURL+"/recover/end", query.Encode())
|
||||
}
|
||||
|
||||
p := path.Join(r.Config.Paths.Mount, "recover/end")
|
||||
return fmt.Sprintf("%s%s?%s", r.Config.Paths.RootURL, p, query.Encode())
|
||||
}
|
||||
|
||||
// GenerateRecoverCreds generates pieces needed for user recovery
|
||||
// selector: hash of the first half of a 64 byte value (to be stored in the database and used in SELECT query)
|
||||
// verifier: hash of the second half of a 64 byte value (to be stored in database but never used in SELECT query)
|
||||
|
@ -409,6 +409,26 @@ func TestEndPostUserNotExist(t *testing.T) {
|
||||
invalidCheck(t, h, w)
|
||||
}
|
||||
|
||||
func TestMailURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
h := testSetup()
|
||||
h.ab.Config.Paths.RootURL = "https://api.test.com:6343"
|
||||
h.ab.Config.Paths.Mount = "/v1/auth"
|
||||
|
||||
want := "https://api.test.com:6343/v1/auth/recover/end?token=abc"
|
||||
if got := h.recover.mailURL("abc"); got != want {
|
||||
t.Error("want:", want, "got:", got)
|
||||
}
|
||||
|
||||
h.ab.Config.Mail.RootURL = "https://test.com:3333/testauth"
|
||||
|
||||
want = "https://test.com:3333/testauth/recover/end?token=abc"
|
||||
if got := h.recover.mailURL("abc"); got != want {
|
||||
t.Error("want:", want, "got:", got)
|
||||
}
|
||||
}
|
||||
|
||||
func invalidCheck(t *testing.T, h *testHarness, w *httptest.ResponseRecorder) {
|
||||
t.Helper()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user