Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
229
verify.go3 kB
package email_verify import ( "context" "fmt" "net/mail" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fctx" "github.com/Southclaws/fault/ftag" "github.com/matcornic/hermes/v2" "github.com/Southclaws/storyden/app/resources/account" "github.com/Southclaws/storyden/app/resources/account/email" "github.com/Southclaws/storyden/app/resources/settings" "github.com/Southclaws/storyden/app/services/comms/mailqueue" ) var ( ErrNotFound = fault.New("no verification code match found", ftag.With(ftag.Unauthenticated)) ErrAccountNotFound = fault.New("no account was found", ftag.With(ftag.NotFound)) ) type Verifier struct { emailRepo *email.Repository mailqueue *mailqueue.Queuer settings *settings.SettingsRepository } func New( emailRepo *email.Repository, mailqueue *mailqueue.Queuer, settings *settings.SettingsRepository, ) *Verifier { return &Verifier{ emailRepo: emailRepo, mailqueue: mailqueue, settings: settings, } } // BeginEmailVerification adds an email record for the specified account, sets // it to unverified and sends an email to the address with a verification code. // You can also optionally supply an authentication record ID to link the email // record to an authentication record to indicate the email is used for login. func (s *Verifier) BeginEmailVerification( ctx context.Context, accountID account.AccountID, address mail.Address, code string, ) (*account.EmailAddress, error) { ae, err := s.emailRepo.Add(ctx, accountID, address, code) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return ae, s.sendVerification(ctx, address, code) } func (s *Verifier) sendVerification(ctx context.Context, address mail.Address, code string) error { set, err := s.settings.Get(ctx) if err != nil { return fault.Wrap(err, fctx.With(ctx)) } recipientName := address.Address instanceTitle := set.Title.Or(settings.DefaultTitle) welcome := fmt.Sprintf("Welcome to %s!", instanceTitle) return s.mailqueue.Queue(ctx, address, recipientName, welcome, []string{welcome}, []hermes.Action{ { Instructions: "Please use the following code to verify your account:", InviteCode: code, }, }) } func (s *Verifier) ResendVerification(ctx context.Context, address mail.Address) error { code, err := s.emailRepo.GetCode(ctx, address) if err != nil { return fault.Wrap(err, fctx.With(ctx)) } return s.sendVerification(ctx, address, code) } func (s *Verifier) Verify(ctx context.Context, emailAddress mail.Address, code string) (*account.Account, error) { acc, exists, err := s.emailRepo.LookupCode(ctx, emailAddress, code) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } if !exists { return nil, fault.Wrap(ErrNotFound, fctx.With(ctx)) } if err := acc.RejectSuspended(); err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } err = s.emailRepo.Verify(ctx, acc.ID, emailAddress) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return acc, nil }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server