| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package user
- import (
- "fmt"
- "net/http"
- "net/url"
- "github.com/porter-dev/porter/api/server/handlers"
- "github.com/porter-dev/porter/api/server/shared"
- "github.com/porter-dev/porter/api/server/shared/apierrors"
- "github.com/porter-dev/porter/api/server/shared/config"
- "github.com/porter-dev/porter/api/types"
- "github.com/porter-dev/porter/internal/analytics"
- "github.com/porter-dev/porter/internal/models"
- "github.com/porter-dev/porter/internal/notifier"
- )
- type VerifyEmailInitiateHandler struct {
- handlers.PorterHandler
- }
- func NewVerifyEmailInitiateHandler(
- config *config.Config,
- ) *VerifyEmailInitiateHandler {
- return &VerifyEmailInitiateHandler{
- PorterHandler: handlers.NewDefaultPorterHandler(config, nil, nil),
- }
- }
- func (v *VerifyEmailInitiateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- user, _ := r.Context().Value(types.UserScope).(*models.User)
- err := startEmailVerification(v.Config(), w, r, user)
- if err != nil {
- v.HandleAPIError(w, r, apierrors.NewErrInternal(err))
- }
- }
- type VerifyEmailFinalizeHandler struct {
- handlers.PorterHandlerReader
- }
- func NewVerifyEmailFinalizeHandler(
- config *config.Config,
- decoderValidator shared.RequestDecoderValidator,
- ) *VerifyEmailFinalizeHandler {
- return &VerifyEmailFinalizeHandler{
- PorterHandlerReader: handlers.NewDefaultPorterHandler(config, decoderValidator, nil),
- }
- }
- func (v *VerifyEmailFinalizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- user, _ := r.Context().Value(types.UserScope).(*models.User)
- request := &types.VerifyEmailFinalizeRequest{}
- if err := v.DecodeAndValidateNoWrite(r, request); err != nil {
- http.Redirect(w, r, "/dashboard?error="+url.QueryEscape(err.Error()), 302)
- return
- }
- token, err := VerifyToken(
- v.Repo().PWResetToken(),
- handlers.IgnoreAPIError,
- w,
- r,
- &request.VerifyTokenFinalizeRequest,
- user.Email,
- )
- if err != nil {
- http.Redirect(w, r, "/dashboard?error="+url.QueryEscape("Email verification error: valid token required"), 302)
- return
- }
- user.EmailVerified = true
- user, err = v.Repo().User().UpdateUser(user)
- if err != nil {
- http.Redirect(w, r, "/dashboard?error="+url.QueryEscape("Could not verify email address"), 302)
- return
- }
- // invalidate the token
- token.IsValid = false
- _, err = v.Repo().PWResetToken().UpdatePWResetToken(token)
- if err != nil {
- http.Redirect(w, r, "/dashboard?error="+url.QueryEscape("Could not verify email address"), 302)
- return
- }
- v.Config().AnalyticsClient.Track(analytics.UserVerifyEmailTrack(&analytics.UserVerifyEmailTrackOpts{
- UserScopedTrackOpts: analytics.GetUserScopedTrackOpts(user.ID),
- Email: user.Email,
- }))
- http.Redirect(w, r, "/dashboard", 302)
- return
- }
- func startEmailVerification(
- config *config.Config,
- w http.ResponseWriter, r *http.Request,
- user *models.User,
- ) error {
- pwReset, rawToken, err := CreatePWResetTokenForEmail(
- config.Repo.PWResetToken(),
- handlers.IgnoreAPIError,
- w,
- r,
- &types.InitiateResetUserPasswordRequest{
- Email: user.Email,
- },
- )
- if err != nil {
- return err
- }
- queryVals := url.Values{
- "token": []string{rawToken},
- "token_id": []string{fmt.Sprintf("%d", pwReset.ID)},
- }
- return config.UserNotifier.SendEmailVerification(
- ¬ifier.SendEmailVerificationOpts{
- Email: user.Email,
- URL: fmt.Sprintf("%s/api/email/verify/finalize?%s", config.ServerConf.ServerURL, queryVals.Encode()),
- },
- )
- }
|