Skip to content

Commit

Permalink
feat: add webhook events and include IP address and user agent in eve…
Browse files Browse the repository at this point in the history
…nt data (#2048)
  • Loading branch information
bjoern-m authored Feb 13, 2025
1 parent 1cf9d62 commit 55d6efb
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 8 deletions.
10 changes: 10 additions & 0 deletions backend/dto/admin/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ type User struct {
Password *PasswordCredential `json:"password,omitempty"`
Identities []Identity `json:"identities,omitempty"`
OTP *OTPDto `json:"otp"`
IPAddress *string `json:"ip_address,omitempty"`
UserAgent *string `json:"user_agent,omitempty"`
}

func (u *User) SetIPAddress(ip string) {
u.IPAddress = &ip
}

func (u *User) SetUserAgent(agent string) {
u.UserAgent = &agent
}

// FromUserModel Converts the DB model to a DTO object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/teamhanko/hanko/backend/flow_api/services"
"github.com/teamhanko/hanko/backend/flowpilot"
"github.com/teamhanko/hanko/backend/persistence/models"
"github.com/teamhanko/hanko/backend/webhooks/events"
"github.com/teamhanko/hanko/backend/webhooks/utils"
)

type PasswordRecovery struct {
Expand Down Expand Up @@ -81,6 +83,8 @@ func (a PasswordRecovery) Execute(c flowpilot.ExecutionContext) error {
return fmt.Errorf("failed to set pw_recovery_pending to the stash: %w", err)
}

utils.NotifyUserChange(deps.HttpContext, deps.Tx, deps.Persister, events.UserPasswordChange, uuid.FromStringOrNil(authUserID))

err = c.ExecuteHook(shared.ScheduleMFACreationStates{})
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions backend/flow_api/flow/flows.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func NewLoginFlow(debug bool) flowpilot.Flow {
BeforeState(shared.StateLoginInit,
login.WebauthnGenerateRequestOptionsForConditionalUi{}).
BeforeState(shared.StateSuccess,
login.TriggerLoginWebhook{},
device_trust.IssueTrustDeviceCookie{},
shared.IssueSession{},
shared.GetUserData{}).
Expand Down
20 changes: 20 additions & 0 deletions backend/flow_api/flow/login/hook_trigger_login_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package login

import (
"github.com/gofrs/uuid"
"github.com/teamhanko/hanko/backend/flow_api/flow/shared"
"github.com/teamhanko/hanko/backend/flowpilot"
"github.com/teamhanko/hanko/backend/webhooks/events"
"github.com/teamhanko/hanko/backend/webhooks/utils"
)

type TriggerLoginWebhook struct {
shared.Action
}

func (h TriggerLoginWebhook) Execute(c flowpilot.HookExecutionContext) error {
deps := h.GetDeps(c)
userID := uuid.FromStringOrNil(c.Stash().Get(shared.StashPathUserID).String())
utils.NotifyUserChange(deps.HttpContext, deps.Tx, deps.Persister, events.UserLogin, userID)
return nil
}
7 changes: 1 addition & 6 deletions backend/flow_api/flow/profile/action_account_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package profile
import (
"fmt"
auditlog "github.com/teamhanko/hanko/backend/audit_log"
"github.com/teamhanko/hanko/backend/dto/admin"
"github.com/teamhanko/hanko/backend/flow_api/flow/shared"
"github.com/teamhanko/hanko/backend/flowpilot"
"github.com/teamhanko/hanko/backend/persistence/models"
Expand Down Expand Up @@ -62,11 +61,7 @@ func (a AccountDelete) Execute(c flowpilot.ExecutionContext) error {
}

deps.HttpContext.SetCookie(cookie)

err = utils.TriggerWebhooks(deps.HttpContext, deps.Tx, events.UserDelete, admin.FromUserModel(*userModel))
if err != nil {
return fmt.Errorf("failed to trrigger webhook: %w", err)
}
utils.NotifyUserChange(deps.HttpContext, deps.Tx, deps.Persister, events.UserDelete, userModel.ID)

return c.Continue(shared.StateProfileAccountDeleted)
}
4 changes: 4 additions & 0 deletions backend/flow_api/flow/profile/action_password_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/teamhanko/hanko/backend/flow_api/flow/shared"
"github.com/teamhanko/hanko/backend/flowpilot"
"github.com/teamhanko/hanko/backend/persistence/models"
"github.com/teamhanko/hanko/backend/webhooks/events"
"github.com/teamhanko/hanko/backend/webhooks/utils"
)

type PasswordUpdate struct {
Expand Down Expand Up @@ -72,5 +74,7 @@ func (a PasswordUpdate) Execute(c flowpilot.ExecutionContext) error {
return fmt.Errorf("could not create audit log: %w", err)
}

utils.NotifyUserChange(deps.HttpContext, deps.Tx, deps.Persister, events.UserPasswordChange, userModel.ID)

return c.Continue(shared.StateProfileInit)
}
4 changes: 3 additions & 1 deletion backend/webhooks/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Event string

const (
User Event = "user"
UserLogin Event = "user.login"
UserCreate Event = "user.create"
UserUpdate Event = "user.update"
UserDelete Event = "user.delete"
Expand All @@ -17,6 +18,7 @@ const (
UserUsernameCreate Event = "user.update.username.create"
UserUsernameDelete Event = "user.update.username.delete"
UserUsernameUpdate Event = "user.update.username.update"
UserPasswordChange Event = "user.update.password.update"

EmailSend Event = "email.send"
)
Expand All @@ -29,7 +31,7 @@ func StringIsValidEvent(value string) bool {
func IsValidEvent(evt Event) bool {
var isValid bool
switch evt {
case User, UserCreate, UserUpdate, UserDelete, UserEmail, UserEmailCreate, UserEmailPrimary, UserEmailDelete, UserUsername, UserUsernameCreate, UserUsernameUpdate, UserUsernameDelete, EmailSend:
case User, UserLogin, UserCreate, UserUpdate, UserDelete, UserEmail, UserEmailCreate, UserEmailPrimary, UserEmailDelete, UserUsername, UserUsernameCreate, UserUsernameUpdate, UserUsernameDelete, UserPasswordChange, EmailSend:
isValid = true
default:
isValid = false
Expand Down
6 changes: 5 additions & 1 deletion backend/webhooks/utils/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ func NotifyUserChange(ctx echo.Context, tx *pop.Connection, persister persistenc
return
}

err = TriggerWebhooks(ctx, tx, event, admin.FromUserModel(*updatedUser))
user := admin.FromUserModel(*updatedUser)
user.SetUserAgent(ctx.Request().UserAgent())
user.SetIPAddress(ctx.RealIP())

err = TriggerWebhooks(ctx, tx, event, user)
if err != nil {
ctx.Logger().Warn(err)
}
Expand Down

0 comments on commit 55d6efb

Please sign in to comment.