{formErrorCode && (
diff --git a/apps/remix/app/components/general/document-signing/document-signing-auth-set-password.tsx b/apps/remix/app/components/general/document-signing/document-signing-auth-set-password.tsx
new file mode 100644
index 000000000..b827c1cbf
--- /dev/null
+++ b/apps/remix/app/components/general/document-signing/document-signing-auth-set-password.tsx
@@ -0,0 +1,63 @@
+import { isSigninEnabledForProvider } from '@documenso/lib/constants/auth';
+import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
+import { Button } from '@documenso/ui/primitives/button';
+import { DialogFooter } from '@documenso/ui/primitives/dialog';
+import { Trans } from '@lingui/react/macro';
+
+import { PasswordSetupRequest } from '~/components/forms/password-setup-request';
+
+export type DocumentSigningAuthSetPasswordProps = {
+ onOpenChange: (value: boolean) => void;
+};
+
+/**
+ * Shown in place of the password reauth form when the signed in user has no
+ * password (e.g. they signed up via OAuth or a passkey).
+ *
+ * Password based action auth is meant to prove more than possession of a session,
+ * so rather than letting the session set a password inline we send the user the
+ * verified reset link and ask them to come back.
+ */
+export const DocumentSigningAuthSetPassword = ({ onOpenChange }: DocumentSigningAuthSetPasswordProps) => {
+ const isEmailPasswordSigninEnabled = isSigninEnabledForProvider('email');
+
+ return (
+
+ {isEmailPasswordSigninEnabled ? (
+ <>
+
+
+ No password set
+
+
+
+ Signing this field requires a password, but your account does not have one. We can email you a link to
+ set one. Once done, sign in again and return to this document to continue.
+
+
+
+
+
+ >
+ ) : (
+
+
+ Password authentication unavailable
+
+
+
+ Your account does not have a password and password sign in is disabled for this instance. Please contact
+ the document sender to use a different authentication method.
+
+
+
+ )}
+
+
+
+
+
+ );
+};
diff --git a/apps/remix/app/components/general/document/document-edit-form.tsx b/apps/remix/app/components/general/document/document-edit-form.tsx
index 051ee562c..06bedf4b6 100644
--- a/apps/remix/app/components/general/document/document-edit-form.tsx
+++ b/apps/remix/app/components/general/document/document-edit-form.tsx
@@ -28,6 +28,7 @@ import { useNavigate, useSearchParams } from 'react-router';
import { z } from 'zod';
import PDFViewerLazy from '~/components/general/pdf-viewer/pdf-viewer-lazy';
import { useCurrentTeam } from '~/providers/team';
+import { useCspNonce } from '~/utils/nonce';
import { getDistributeErrorMessage } from '~/utils/toast-error-messages';
export type DocumentEditFormProps = {
@@ -42,6 +43,7 @@ const EditDocumentSteps: EditDocumentStep[] = ['settings', 'signers', 'fields',
export const DocumentEditForm = ({ className, initialDocument, documentRootPath }: DocumentEditFormProps) => {
const { toast } = useToast();
const { _ } = useLingui();
+ const cspNonce = useCspNonce();
const navigate = useNavigate();
@@ -473,6 +475,7 @@ export const DocumentEditForm = ({ className, initialDocument, documentRootPath
onSubmit={onAddSignersFormSubmit}
onAutoSave={onAddSignersFormAutoSave}
isDocumentPdfLoaded={isDocumentPdfLoaded}
+ nonce={cspNonce}
/>
{
const { t, i18n } = useLingui();
const analytics = useAnalytics();
@@ -359,6 +362,9 @@ export const EnvelopeEditorFieldsPageRenderer = ({ pageData }: { pageData: PageR
shouldOverdrawWholeArea: true,
ignoreStroke: true,
flipEnabled: false,
+ anchorStyleFunc: (anchor) => {
+ anchor.hitStrokeWidth(TRANSFORMER_ANCHOR_HIT_STROKE_PX / scale);
+ },
boundBoxFunc: (oldBox, newBox) => {
// Enforce minimum size
if (newBox.width < 30 || newBox.height < 20) {
diff --git a/apps/remix/app/components/general/envelope-editor/envelope-editor-recipient-form.tsx b/apps/remix/app/components/general/envelope-editor/envelope-editor-recipient-form.tsx
index cff9bab64..b3173b547 100644
--- a/apps/remix/app/components/general/envelope-editor/envelope-editor-recipient-form.tsx
+++ b/apps/remix/app/components/general/envelope-editor/envelope-editor-recipient-form.tsx
@@ -45,6 +45,7 @@ import { isDeepEqual } from 'remeda';
import { AiFeaturesEnableDialog } from '~/components/dialogs/ai-features-enable-dialog';
import { AiRecipientDetectionDialog } from '~/components/dialogs/ai-recipient-detection-dialog';
import { useCurrentTeam } from '~/providers/team';
+import { useCspNonce } from '~/utils/nonce';
export const EnvelopeEditorRecipientForm = () => {
const { envelope, setRecipientsDebounced, updateEnvelope, editorRecipients, isEmbedded, editorConfig } =
@@ -52,6 +53,7 @@ export const EnvelopeEditorRecipientForm = () => {
const organisation = useCurrentOrganisation();
const team = useCurrentTeam();
+ const cspNonce = useCspNonce();
const { t } = useLingui();
const { toast } = useToast();
@@ -795,6 +797,7 @@ export const EnvelopeEditorRecipientForm = () => {