Add fullName to magic link form

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-03-04 13:59:28 +04:00
parent b31b68f1d2
commit 9e106a8875
7 changed files with 36 additions and 16 deletions

View File

@@ -37,6 +37,7 @@ const sendMagicLinkMutation = graphql`
`; `;
const schema = z.object({ const schema = z.object({
fullName: z.string().min(2),
email: z.string().email(), email: z.string().email(),
}); });
@@ -103,6 +104,7 @@ export function ConnectPage(props: {
} = useFormWithSchema(schema, { } = useFormWithSchema(schema, {
defaultValues: { defaultValues: {
email: "", email: "",
fullName: "",
}, },
}); });
@@ -110,8 +112,8 @@ export function ConnectPage(props: {
sendMagicLinkMutation, sendMagicLinkMutation,
); );
const handleSubmit = handleSubmitWrapper(({ email }: FormData) => { const handleSubmit = handleSubmitWrapper(({ email, fullName }: FormData) => {
const input: SendMagicLinkInput = { email }; const input: SendMagicLinkInput = { email, fullName };
if (safeContinueUrl) { if (safeContinueUrl) {
input.continue = safeContinueUrl; input.continue = safeContinueUrl;
} }
@@ -119,6 +121,7 @@ export function ConnectPage(props: {
variables: { variables: {
input: { input: {
email, email,
fullName,
continue: safeContinueUrl, continue: safeContinueUrl,
}, },
}, },
@@ -170,11 +173,20 @@ export function ConnectPage(props: {
</div> </div>
<form onSubmit={e => void handleSubmit(e)} className="space-y-6"> <form onSubmit={e => void handleSubmit(e)} className="space-y-6">
<Field
label={__("Full Name")}
placeholder="John Doe"
{...register("fullName")}
type="text"
required
error={formState.errors.fullName?.message}
/>
<Field <Field
label={__("Email")} label={__("Email")}
placeholder="john.doe@acme.com" placeholder="john.doe@acme.com"
{...register("email")} {...register("email")}
type="email" type="email"
required
error={formState.errors.email?.message} error={formState.errors.email?.message}
/> />

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<711ecaa392c23004a3bd1dfb24a5751f>> * @generated SignedSource<<f567da0a977d6ae788cdd5d6eff1d59f>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
export type SendMagicLinkInput = { export type SendMagicLinkInput = {
continue?: string | null | undefined; continue?: string | null | undefined;
email: any; email: any;
fullName: string;
}; };
export type ConnectPageMutation$variables = { export type ConnectPageMutation$variables = {
input: SendMagicLinkInput; input: SendMagicLinkInput;

View File

@@ -61,6 +61,7 @@ type (
} }
SendMagicLinkRequest struct { SendMagicLinkRequest struct {
FullName string
Email mail.Addr Email mail.Addr
URLPath string URLPath string
OrganizationID gid.GID OrganizationID gid.GID
@@ -74,6 +75,7 @@ type (
} }
MagicLinkData struct { MagicLinkData struct {
FullName string `json:"fullName"`
Email mail.Addr `json:"email"` Email mail.Addr `json:"email"`
Continue *string `json:"continue"` Continue *string `json:"continue"`
} }
@@ -595,6 +597,7 @@ func (s AuthService) SendMagicLink(ctx context.Context, req *SendMagicLinkReques
TokenTypeMagicLink, TokenTypeMagicLink,
s.magicLinkTokenValidity, s.magicLinkTokenValidity,
MagicLinkData{ MagicLinkData{
FullName: req.FullName,
Email: req.Email, Email: req.Email,
Continue: req.Continue, Continue: req.Continue,
}, },
@@ -616,20 +619,9 @@ func (s AuthService) SendMagicLink(ctx context.Context, req *SendMagicLinkReques
return fmt.Errorf("cannot insert token: %w", err) return fmt.Errorf("cannot insert token: %w", err)
} }
fullName := req.Email.Username() fullName := req.FullName
identity := &coredata.Identity{}
organization := &coredata.Organization{} organization := &coredata.Organization{}
if err := identity.LoadByEmail(ctx, tx, req.Email); err == nil {
if identity.FullName != "" {
fullName = identity.FullName
}
} else {
if !errors.Is(err, coredata.ErrResourceNotFound) {
return fmt.Errorf("cannot load identity: %w", err)
}
}
if err := organization.LoadByID(ctx, tx, coredata.NewNoScope(), req.OrganizationID); err != nil { if err := organization.LoadByID(ctx, tx, coredata.NewNoScope(), req.OrganizationID); err != nil {
return fmt.Errorf("cannot load organization: %w", err) return fmt.Errorf("cannot load organization: %w", err)
} }
@@ -728,6 +720,10 @@ func (s AuthService) OpenSessionWithMagicLink(ctx context.Context, tokenString s
UpdatedAt: now, UpdatedAt: now,
} }
if identity.FullName == "" {
identity.FullName = payload.Data.FullName
}
if err := identity.Insert(ctx, tx); err != nil { if err := identity.Insert(ctx, tx); err != nil {
return fmt.Errorf("cannot create identity: %w", err) return fmt.Errorf("cannot create identity: %w", err)
} }

View File

@@ -611,6 +611,7 @@ type DocumentAccess implements Node {
} }
input SendMagicLinkInput { input SendMagicLinkInput {
fullName: String!
email: EmailAddr! email: EmailAddr!
continue: String continue: String
} }

View File

@@ -2033,6 +2033,7 @@ type DocumentAccess implements Node {
} }
input SendMagicLinkInput { input SendMagicLinkInput {
fullName: String!
email: EmailAddr! email: EmailAddr!
continue: String continue: String
} }
@@ -9515,13 +9516,20 @@ func (ec *executionContext) unmarshalInputSendMagicLinkInput(ctx context.Context
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"email", "continue"} fieldsInOrder := [...]string{"fullName", "email", "continue"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
continue continue
} }
switch k { switch k {
case "fullName":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fullName"))
data, err := ec.unmarshalNString2string(ctx, v)
if err != nil {
return it, err
}
it.FullName = data
case "email": case "email":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v) data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)

View File

@@ -214,6 +214,7 @@ type RequestTrustCenterFileAccessInput struct {
} }
type SendMagicLinkInput struct { type SendMagicLinkInput struct {
FullName string `json:"fullName"`
Email mail.Addr `json:"email"` Email mail.Addr `json:"email"`
Continue *string `json:"continue,omitempty"` Continue *string `json:"continue,omitempty"`
} }

View File

@@ -193,6 +193,7 @@ func (r *mutationResolver) SendMagicLink(ctx context.Context, input types.SendMa
} }
req := &iam.SendMagicLinkRequest{ req := &iam.SendMagicLinkRequest{
FullName: input.FullName,
Email: input.Email, Email: input.Email,
CompliancePageID: &trustCenter.ID, CompliancePageID: &trustCenter.ID,
OrganizationID: trustCenter.OrganizationID, OrganizationID: trustCenter.OrganizationID,