github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/invite/impl_applyinvitation.go (about)

     1  /*
     2   * Copyright (c) 2023-present unTill Pro, Ltd.
     3   */
     4  
     5  package invite
     6  
     7  import (
     8  	"fmt"
     9  	"strconv"
    10  	"strings"
    11  
    12  	"github.com/voedger/voedger/pkg/appdef"
    13  	"github.com/voedger/voedger/pkg/istructs"
    14  	"github.com/voedger/voedger/pkg/itokens"
    15  	payloads "github.com/voedger/voedger/pkg/itokens-payloads"
    16  	"github.com/voedger/voedger/pkg/state"
    17  	"github.com/voedger/voedger/pkg/sys/authnz"
    18  	"github.com/voedger/voedger/pkg/sys/smtp"
    19  	coreutils "github.com/voedger/voedger/pkg/utils"
    20  	"github.com/voedger/voedger/pkg/utils/federation"
    21  )
    22  
    23  func asyncProjectorApplyInvitation(timeFunc coreutils.TimeFunc, federation federation.IFederation, tokens itokens.ITokens, smtpCfg smtp.Cfg) istructs.Projector {
    24  	return istructs.Projector{
    25  		Name: qNameAPApplyInvitation,
    26  		Func: applyInvitationProjector(timeFunc, federation, tokens, smtpCfg),
    27  	}
    28  }
    29  
    30  // AFTER EXECUTE ON (InitiateInvitationByEMail)
    31  func applyInvitationProjector(timeFunc coreutils.TimeFunc, federation federation.IFederation, tokens itokens.ITokens, smtpCfg smtp.Cfg) func(event istructs.IPLogEvent, state istructs.IState, intents istructs.IIntents) (err error) {
    32  	return func(event istructs.IPLogEvent, s istructs.IState, intents istructs.IIntents) (err error) {
    33  		skbViewInviteIndex, err := s.KeyBuilder(state.View, qNameViewInviteIndex)
    34  		if err != nil {
    35  			return
    36  		}
    37  		skbViewInviteIndex.PutInt32(field_Dummy, value_Dummy_One)
    38  		skbViewInviteIndex.PutString(Field_Login, event.ArgumentObject().AsString(field_Email))
    39  		svViewInviteIndex, err := s.MustExist(skbViewInviteIndex)
    40  		if err != nil {
    41  			return
    42  		}
    43  
    44  		verificationCode, err := coreutils.EmailVerificationCode()
    45  		if err != nil {
    46  			// notest
    47  			return err
    48  		}
    49  		emailTemplate := coreutils.TruncateEmailTemplate(event.ArgumentObject().AsString(field_EmailTemplate))
    50  
    51  		skbCDocWorkspaceDescriptor, err := s.KeyBuilder(state.Record, authnz.QNameCDocWorkspaceDescriptor)
    52  		if err != nil {
    53  			return
    54  		}
    55  		skbCDocWorkspaceDescriptor.PutQName(state.Field_Singleton, authnz.QNameCDocWorkspaceDescriptor)
    56  		svCDocWorkspaceDescriptor, err := s.MustExist(skbCDocWorkspaceDescriptor)
    57  		if err != nil {
    58  			return
    59  		}
    60  
    61  		replacer := strings.NewReplacer(
    62  			EmailTemplatePlaceholder_VerificationCode, verificationCode,
    63  			EmailTemplatePlaceholder_InviteID, strconv.FormatInt(int64(svViewInviteIndex.AsRecordID(field_InviteID)), base),
    64  			EmailTemplatePlaceholder_WSID, strconv.FormatInt(int64(event.Workspace()), base),
    65  			EmailTemplatePlaceholder_WSName, svCDocWorkspaceDescriptor.AsString(authnz.Field_WSName),
    66  			EmailTemplatePlaceholder_Email, event.ArgumentObject().AsString(field_Email),
    67  		)
    68  
    69  		// Send invitation email
    70  		skbSendMail, err := s.KeyBuilder(state.SendMail, appdef.NullQName)
    71  		if err != nil {
    72  			return
    73  		}
    74  		skbSendMail.PutString(state.Field_Subject, event.ArgumentObject().AsString(field_EmailSubject))
    75  		skbSendMail.PutString(state.Field_To, event.ArgumentObject().AsString(field_Email))
    76  		skbSendMail.PutString(state.Field_Body, replacer.Replace(emailTemplate))
    77  		skbSendMail.PutString(state.Field_From, smtpCfg.GetFrom())
    78  		skbSendMail.PutString(state.Field_Host, smtpCfg.Host)
    79  		skbSendMail.PutInt32(state.Field_Port, smtpCfg.Port)
    80  		skbSendMail.PutString(state.Field_Username, smtpCfg.Username)
    81  
    82  		pwd := ""
    83  		if !coreutils.IsTest() {
    84  			skbAppSecretsStorage, err := s.KeyBuilder(state.AppSecret, appdef.NullQName)
    85  			if err != nil {
    86  				return err
    87  			}
    88  			skbAppSecretsStorage.PutString(state.Field_Secret, smtpCfg.PwdSecret)
    89  			svAppSecretsStorage, err := s.MustExist(skbAppSecretsStorage)
    90  			if err != nil {
    91  				return err
    92  			}
    93  			pwd = svAppSecretsStorage.AsString("")
    94  		}
    95  		skbSendMail.PutString(state.Field_Password, pwd)
    96  
    97  		// Send invitation Email
    98  		_, err = intents.NewValue(skbSendMail)
    99  		if err != nil {
   100  			return
   101  		}
   102  
   103  		// Update cdoc.Invite State=Invited
   104  		appQName := s.App()
   105  		authToken, err := payloads.GetSystemPrincipalToken(tokens, appQName)
   106  		if err != nil {
   107  			return
   108  		}
   109  		_, err = federation.Func(
   110  			fmt.Sprintf("api/%s/%d/c.sys.CUD", appQName, event.Workspace()),
   111  			fmt.Sprintf(`{"cuds":[{"sys.ID":%d,"fields":{"State":%d,"VerificationCode":"%s","Updated":%d}}]}`, svViewInviteIndex.AsRecordID(field_InviteID), State_Invited, verificationCode, timeFunc().UnixMilli()),
   112  			coreutils.WithAuthorizeBy(authToken),
   113  			coreutils.WithDiscardResponse())
   114  
   115  		return err
   116  	}
   117  }