github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/model/instance/lifecycle/magic_link.go (about)

     1  package lifecycle
     2  
     3  import (
     4  	"errors"
     5  	"net/url"
     6  
     7  	"github.com/cozy/cozy-stack/model/instance"
     8  	csettings "github.com/cozy/cozy-stack/model/settings"
     9  	"github.com/cozy/cozy-stack/pkg/crypto"
    10  	"github.com/cozy/cozy-stack/pkg/emailer"
    11  )
    12  
    13  // ErrMagicLinkNotAvailable is used when requesting a magic link on a Cozy
    14  // where this feature has not been activated.
    15  var ErrMagicLinkNotAvailable = errors.New("magic link is not available on this instance")
    16  
    17  // ErrInvalidMagicLink is used when the code for a magic link is invalid
    18  var ErrInvalidMagicLink = errors.New("invalid magic link")
    19  
    20  func SendMagicLink(inst *instance.Instance, redirect string) error {
    21  	code, err := CreateMagicLinkCode(inst)
    22  	if err != nil {
    23  		return err
    24  	}
    25  
    26  	link := inst.PageURL("/auth/magic_link", url.Values{
    27  		"code":     []string{code},
    28  		"redirect": []string{redirect},
    29  	})
    30  	publicName, _ := csettings.PublicName(inst)
    31  	return emailer.SendEmail(inst, &emailer.TransactionalEmailCmd{
    32  		TemplateName: "magic_link",
    33  		TemplateValues: map[string]interface{}{
    34  			"MagicLink":  link,
    35  			"PublicName": publicName,
    36  		},
    37  	})
    38  }
    39  
    40  func CreateMagicLinkCode(inst *instance.Instance) (string, error) {
    41  	if !inst.MagicLink {
    42  		return "", ErrMagicLinkNotAvailable
    43  	}
    44  
    45  	code := crypto.GenerateRandomString(instance.MagicLinkCodeLen)
    46  	if err := GetStore().SaveMagicLinkCode(inst, code); err != nil {
    47  		return "", err
    48  	}
    49  	return code, nil
    50  }
    51  
    52  func CheckMagicLink(inst *instance.Instance, code string) error {
    53  	if !GetStore().CheckMagicLinkCode(inst, code) {
    54  		return ErrInvalidMagicLink
    55  	}
    56  	return nil
    57  }