Skip to content

js-sdk: senderEmail serializes as the literal string "undefined" when unset #51

Description

@nicolasiscoding

Severity: low — latent today, becomes live if the client-side sender requirement is ever relaxed.

What

In packages/js-sdk/src/modules/sign.ts, senderEmail is assigned unconditionally while senderName immediately below it is guarded:

// sign.ts:115 (and again at :196)
formData.senderEmail = request.senderEmail || senderConfig.senderEmail;   // unconditional
if (request.senderName || senderConfig.senderName) {                      // guarded
  formData.senderName = request.senderName || senderConfig.senderName;
}

When neither a request nor a config senderEmail is present, formData.senderEmail is set to undefined. In a multipart upload that serializes to the literal string "undefined", which the backend then rejects:

ValidationError: senderEmail must be a valid email address

That message is confusing: it says the address is malformed when the caller supplied no address at all.

Reproduce

TurboSign.configure({ apiKey, orgId, baseUrl, skipSenderValidation: true });
await TurboSign.createSignatureReviewLink({ file, documentName, recipients, fields });
// -> ValidationError: senderEmail must be a valid email address

Both call sites (:115 and :196) are affected.

Why it is only latent

TurboDocxHttpClient hard-requires senderEmail at construction (http.ts, "senderEmail is required…"), so the only way to reach this today is the skipSenderValidation escape hatch. Normal SDK users cannot hit it.

It stops being latent the moment that client-side requirement is relaxed — and the backend now accepts an omitted sender (see RapidDocxBackend#1611 / PR#1614), so relaxing it is a plausible near-term change. Worth fixing before then, not after.

Fix

Guard it the same way senderName already is:

const resolvedSenderEmail = request.senderEmail || senderConfig.senderEmail;
if (resolvedSenderEmail) {
  formData.senderEmail = resolvedSenderEmail;
}

Apply at both :115 and :196. Worth a quick audit for the same unconditional-assignment pattern on other optional multipart fields.

Note on the client-side requirement itself

Keeping it is deliberate — the backend no longer rejects an omitted sender, but the SDK continuing to require it gives integrators a migration runway and produces a better audit trail. This issue is only about not serialising "undefined" when the value is genuinely absent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions