179 lines
5.6 KiB
Go
179 lines
5.6 KiB
Go
package trust_v1
|
|
|
|
// This file will be automatically regenerated based on the schema, any resolver
|
|
// implementations
|
|
// will be copied through when generating and any unknown code will be moved to the end.
|
|
// Code generated by github.com/99designs/gqlgen version v0.17.90
|
|
|
|
import (
|
|
"context"
|
|
|
|
"errors"
|
|
"go.gearno.de/kit/log"
|
|
"go.probo.inc/probo/pkg/baseurl"
|
|
"go.probo.inc/probo/pkg/coredata"
|
|
"go.probo.inc/probo/pkg/iam"
|
|
"go.probo.inc/probo/pkg/saferedirect"
|
|
"go.probo.inc/probo/pkg/server/api/authn"
|
|
"go.probo.inc/probo/pkg/server/api/compliancepage"
|
|
"go.probo.inc/probo/pkg/server/api/trust/v1/types"
|
|
"go.probo.inc/probo/pkg/server/gqlutils"
|
|
)
|
|
|
|
// SendMagicLink is the resolver for the sendMagicLink field.
|
|
func (r *mutationResolver) SendMagicLink(ctx context.Context, input types.SendMagicLinkInput) (*types.SendMagicLinkPayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
baseURL := compliancepage.CompliancePageBaseURLFromContext(ctx)
|
|
|
|
safeRedirect := saferedirect.New(saferedirect.StaticHosts(baseurl.MustParse(*baseURL).Host()))
|
|
|
|
if input.Continue != nil {
|
|
_, ok := safeRedirect.Validate(ctx, *input.Continue)
|
|
if !ok {
|
|
return nil, gqlutils.Invalidf(ctx, "invalid continue URL")
|
|
}
|
|
}
|
|
|
|
req := &iam.SendMagicLinkRequest{
|
|
Email: input.Email,
|
|
CompliancePageID: &trustCenter.ID,
|
|
OrganizationID: trustCenter.OrganizationID,
|
|
URLPath: "verify-magic-link",
|
|
Continue: input.Continue,
|
|
}
|
|
|
|
if err := r.iam.AuthService.SendMagicLink(ctx, req); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot send magic link", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
// VerifyMagicLink is the resolver for the verifyMagicLink field.
|
|
func (r *mutationResolver) VerifyMagicLink(ctx context.Context, input types.VerifyMagicLinkInput) (*types.VerifyMagicLinkPayload, error) {
|
|
session := authn.SessionFromContext(ctx)
|
|
identity := authn.IdentityFromContext(ctx)
|
|
|
|
email, err := r.iam.AuthService.GetMagicLinkEmail(ctx, input.Token)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrExpiredToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrInvalidToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get magic link email", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
var continueURL *string
|
|
|
|
switch {
|
|
case session == nil:
|
|
var err error
|
|
|
|
identity, session, continueURL, err = r.iam.AuthService.OpenSessionWithMagicLink(ctx, input.Token)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrExpiredToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrInvalidToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot open session with magic link", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
case identity.EmailAddress != email:
|
|
if err := r.iam.SessionService.CloseSession(ctx, session.ID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot close session", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
var err error
|
|
|
|
identity, session, continueURL, err = r.iam.AuthService.OpenSessionWithMagicLink(ctx, input.Token)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrExpiredToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrInvalidToken](err); ok {
|
|
return nil, gqlutils.Invalid(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot open session with magic link", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
}
|
|
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
if _, err := r.trust.ProvisionMember(ctx, trustCenter.ID, identity.ID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot provision member", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
w := gqlutils.HTTPResponseWriterFromContext(ctx)
|
|
r.sessionCookie.Set(w, session)
|
|
|
|
return &types.VerifyMagicLinkPayload{
|
|
Continue: continueURL,
|
|
}, nil
|
|
}
|
|
|
|
// UpdateFullName is the resolver for the updateFullName field.
|
|
func (r *mutationResolver) UpdateFullName(ctx context.Context, input types.UpdateFullNameInput) (*types.UpdateFullNamePayload, error) {
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
|
}
|
|
|
|
identity, err := r.iam.AccountService.UpdateIdentity(
|
|
ctx,
|
|
identity.ID,
|
|
&iam.UpdateIdentityRequest{
|
|
FullName: input.FullName,
|
|
},
|
|
)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot update identity", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
profile, err := r.iam.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, compliancePage.OrganizationID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrProfileNotFound](err); !ok {
|
|
r.logger.ErrorCtx(ctx, "cannot get profile", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
}
|
|
|
|
if profile.Source == coredata.ProfileSourceManual {
|
|
if _, err := r.iam.OrganizationService.UpdateUser(ctx, &iam.UpdateUserRequest{
|
|
ID: profile.ID,
|
|
FullName: identity.FullName,
|
|
AdditionalEmailAddresses: profile.AdditionalEmailAddresses,
|
|
Kind: profile.Kind,
|
|
Position: profile.Position,
|
|
ContractStartDate: &profile.ContractStartDate,
|
|
ContractEndDate: &profile.ContractEndDate,
|
|
}); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot update profile", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
}
|
|
|
|
return &types.UpdateFullNamePayload{Success: true}, nil
|
|
}
|