mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 07:43:16 +10:00
fix: update reauth constraints and tests
This commit is contained in:
@ -124,7 +124,8 @@ test('[DOCUMENT_AUTH]: should allow signing with valid global auth', async ({ pa
|
||||
await unseedUser(recipientWithAccount.id);
|
||||
});
|
||||
|
||||
test('[DOCUMENT_AUTH]: should deny signing document when required for global auth', async ({
|
||||
// Currently document auth for signing/approving/viewing is not required.
|
||||
test.skip('[DOCUMENT_AUTH]: should deny signing document when required for global auth', async ({
|
||||
page,
|
||||
}) => {
|
||||
const user = await seedUser();
|
||||
@ -184,6 +185,10 @@ test('[DOCUMENT_AUTH]: should deny signing fields when required for global auth'
|
||||
await expect(page.getByRole('heading', { name: 'Sign Document' })).toBeVisible();
|
||||
|
||||
for (const field of Field) {
|
||||
if (field.type !== FieldType.SIGNATURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await page.locator(`#field-${field.id}`).getByRole('button').click();
|
||||
await expect(page.getByRole('paragraph')).toContainText(
|
||||
'Reauthentication is required to sign the field',
|
||||
@ -249,6 +254,10 @@ test('[DOCUMENT_AUTH]: should allow field signing when required for recipient au
|
||||
|
||||
if (isAuthRequired) {
|
||||
for (const field of Field) {
|
||||
if (field.type !== FieldType.SIGNATURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await page.locator(`#field-${field.id}`).getByRole('button').click();
|
||||
await expect(page.getByRole('paragraph')).toContainText(
|
||||
'Reauthentication is required to sign the field',
|
||||
@ -356,6 +365,10 @@ test('[DOCUMENT_AUTH]: should allow field signing when required for recipient an
|
||||
|
||||
if (isAuthRequired) {
|
||||
for (const field of Field) {
|
||||
if (field.type !== FieldType.SIGNATURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await page.locator(`#field-${field.id}`).getByRole('button').click();
|
||||
await expect(page.getByRole('paragraph')).toContainText(
|
||||
'Reauthentication is required to sign the field',
|
||||
|
||||
@ -4,17 +4,21 @@ import path from 'node:path';
|
||||
import { getDocumentByToken } from '@documenso/lib/server-only/document/get-document-by-token';
|
||||
import { getRecipientByEmail } from '@documenso/lib/server-only/recipient/get-recipient-by-email';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import { TEST_USER } from '@documenso/prisma/seed/pr-718-add-stepper-component';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
|
||||
import { apiSignin } from './fixtures/authentication';
|
||||
|
||||
test(`[PR-718]: should be able to create a document`, async ({ page }) => {
|
||||
await page.goto('/signin');
|
||||
|
||||
const documentTitle = `example-${Date.now()}.pdf`;
|
||||
|
||||
// Sign in
|
||||
await page.getByLabel('Email').fill(TEST_USER.email);
|
||||
await page.getByLabel('Password', { exact: true }).fill(TEST_USER.password);
|
||||
await page.getByRole('button', { name: 'Sign In' }).click();
|
||||
const user = await seedUser();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
});
|
||||
|
||||
// Upload document
|
||||
const [fileChooser] = await Promise.all([
|
||||
@ -82,10 +86,12 @@ test('should be able to create a document with multiple recipients', async ({ pa
|
||||
|
||||
const documentTitle = `example-${Date.now()}.pdf`;
|
||||
|
||||
// Sign in
|
||||
await page.getByLabel('Email').fill(TEST_USER.email);
|
||||
await page.getByLabel('Password', { exact: true }).fill(TEST_USER.password);
|
||||
await page.getByRole('button', { name: 'Sign In' }).click();
|
||||
const user = await seedUser();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
});
|
||||
|
||||
// Upload document
|
||||
const [fileChooser] = await Promise.all([
|
||||
@ -103,7 +109,7 @@ test('should be able to create a document with multiple recipients', async ({ pa
|
||||
await page.waitForURL(/\/documents\/\d+/);
|
||||
|
||||
// Set title
|
||||
await expect(page.getByRole('heading', { name: 'Add Title' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
|
||||
|
||||
await page.getByLabel('Title').fill(documentTitle);
|
||||
|
||||
@ -112,13 +118,12 @@ test('should be able to create a document with multiple recipients', async ({ pa
|
||||
// Add signers
|
||||
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
|
||||
|
||||
await page.getByLabel('Email*').fill('user1@example.com');
|
||||
await page.getByLabel('Name').fill('User 1');
|
||||
|
||||
// Add 2 signers.
|
||||
await page.getByPlaceholder('Email').fill('user1@example.com');
|
||||
await page.getByPlaceholder('Name').fill('User 1');
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
await page.getByLabel('Email*').nth(1).fill('user2@example.com');
|
||||
await page.getByLabel('Name').nth(1).fill('User 2');
|
||||
await page.getByRole('textbox', { name: 'Email', exact: true }).fill('user2@example.com');
|
||||
await page.getByRole('textbox', { name: 'Name', exact: true }).fill('User 2');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
@ -177,10 +182,12 @@ test('should be able to create, send and sign a document', async ({ page }) => {
|
||||
|
||||
const documentTitle = `example-${Date.now()}.pdf`;
|
||||
|
||||
// Sign in
|
||||
await page.getByLabel('Email').fill(TEST_USER.email);
|
||||
await page.getByLabel('Password', { exact: true }).fill(TEST_USER.password);
|
||||
await page.getByRole('button', { name: 'Sign In' }).click();
|
||||
const user = await seedUser();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
});
|
||||
|
||||
// Upload document
|
||||
const [fileChooser] = await Promise.all([
|
||||
@ -198,7 +205,7 @@ test('should be able to create, send and sign a document', async ({ page }) => {
|
||||
await page.waitForURL(/\/documents\/\d+/);
|
||||
|
||||
// Set title
|
||||
await expect(page.getByRole('heading', { name: 'Add Title' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
|
||||
|
||||
await page.getByLabel('Title').fill(documentTitle);
|
||||
|
||||
@ -207,8 +214,8 @@ test('should be able to create, send and sign a document', async ({ page }) => {
|
||||
// Add signers
|
||||
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
|
||||
|
||||
await page.getByLabel('Email*').fill('user1@example.com');
|
||||
await page.getByLabel('Name').fill('User 1');
|
||||
await page.getByPlaceholder('Email').fill('user1@example.com');
|
||||
await page.getByPlaceholder('Name').fill('User 1');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
@ -225,8 +232,9 @@ test('should be able to create, send and sign a document', async ({ page }) => {
|
||||
// Assert document was created
|
||||
await expect(page.getByRole('link', { name: documentTitle })).toBeVisible();
|
||||
await page.getByRole('link', { name: documentTitle }).click();
|
||||
await page.waitForURL(/\/documents\/\d+/);
|
||||
|
||||
const url = await page.url().split('/');
|
||||
const url = page.url().split('/');
|
||||
const documentId = url[url.length - 1];
|
||||
|
||||
const { token } = await getRecipientByEmail({
|
||||
@ -260,10 +268,12 @@ test('should be able to create, send with redirect url, sign a document and redi
|
||||
|
||||
const documentTitle = `example-${Date.now()}.pdf`;
|
||||
|
||||
// Sign in
|
||||
await page.getByLabel('Email').fill(TEST_USER.email);
|
||||
await page.getByLabel('Password', { exact: true }).fill(TEST_USER.password);
|
||||
await page.getByRole('button', { name: 'Sign In' }).click();
|
||||
const user = await seedUser();
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
});
|
||||
|
||||
// Upload document
|
||||
const [fileChooser] = await Promise.all([
|
||||
@ -280,18 +290,19 @@ test('should be able to create, send with redirect url, sign a document and redi
|
||||
// Wait to be redirected to the edit page
|
||||
await page.waitForURL(/\/documents\/\d+/);
|
||||
|
||||
// Set title
|
||||
await expect(page.getByRole('heading', { name: 'Add Title' })).toBeVisible();
|
||||
|
||||
// Set title & advanced redirect
|
||||
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
|
||||
await page.getByLabel('Title').fill(documentTitle);
|
||||
await page.getByRole('button', { name: 'Advanced Options' }).click();
|
||||
await page.getByLabel('Redirect URL').fill('https://documenso.com');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
// Add signers
|
||||
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
|
||||
|
||||
await page.getByLabel('Email*').fill('user1@example.com');
|
||||
await page.getByLabel('Name').fill('User 1');
|
||||
await page.getByPlaceholder('Email').fill('user1@example.com');
|
||||
await page.getByPlaceholder('Name').fill('User 1');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
@ -299,11 +310,6 @@ test('should be able to create, send with redirect url, sign a document and redi
|
||||
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
// Add subject and send
|
||||
await expect(page.getByRole('heading', { name: 'Add Subject' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Advanced Options' }).click();
|
||||
await page.getByLabel('Redirect URL').fill('https://documenso.com');
|
||||
|
||||
await page.getByRole('button', { name: 'Send' }).click();
|
||||
|
||||
await page.waitForURL('/documents');
|
||||
@ -311,8 +317,9 @@ test('should be able to create, send with redirect url, sign a document and redi
|
||||
// Assert document was created
|
||||
await expect(page.getByRole('link', { name: documentTitle })).toBeVisible();
|
||||
await page.getByRole('link', { name: documentTitle }).click();
|
||||
await page.waitForURL(/\/documents\/\d+/);
|
||||
|
||||
const url = await page.url().split('/');
|
||||
const url = page.url().split('/');
|
||||
const documentId = url[url.length - 1];
|
||||
|
||||
const { token } = await getRecipientByEmail({
|
||||
|
||||
@ -7,11 +7,8 @@ import { prisma } from '@documenso/prisma';
|
||||
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { TRecipientActionAuth } from '../../types/document-auth';
|
||||
import { extractDocumentAuthMethods } from '../../utils/document-auth';
|
||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||
import { isRecipientAuthorized } from './is-recipient-authorized';
|
||||
import { sealDocument } from './seal-document';
|
||||
import { sendPendingEmail } from './send-pending-email';
|
||||
|
||||
@ -46,8 +43,6 @@ const getDocument = async ({ token, documentId }: CompleteDocumentWithTokenOptio
|
||||
export const completeDocumentWithToken = async ({
|
||||
token,
|
||||
documentId,
|
||||
userId,
|
||||
authOptions,
|
||||
requestMetadata,
|
||||
}: CompleteDocumentWithTokenOptions) => {
|
||||
'use server';
|
||||
@ -79,22 +74,24 @@ export const completeDocumentWithToken = async ({
|
||||
throw new Error(`Recipient ${recipient.id} has unsigned fields`);
|
||||
}
|
||||
|
||||
const { derivedRecipientActionAuth } = extractDocumentAuthMethods({
|
||||
documentAuth: document.authOptions,
|
||||
recipientAuth: recipient.authOptions,
|
||||
});
|
||||
// Document reauth for completing documents is currently not required.
|
||||
|
||||
const isValid = await isRecipientAuthorized({
|
||||
type: 'ACTION',
|
||||
document: document,
|
||||
recipient: recipient,
|
||||
userId,
|
||||
authOptions,
|
||||
});
|
||||
// const { derivedRecipientActionAuth } = extractDocumentAuthMethods({
|
||||
// documentAuth: document.authOptions,
|
||||
// recipientAuth: recipient.authOptions,
|
||||
// });
|
||||
|
||||
if (!isValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||
}
|
||||
// const isValid = await isRecipientAuthorized({
|
||||
// type: 'ACTION',
|
||||
// document: document,
|
||||
// recipient: recipient,
|
||||
// userId,
|
||||
// authOptions,
|
||||
// });
|
||||
|
||||
// if (!isValid) {
|
||||
// throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||
// }
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.recipient.update({
|
||||
@ -121,7 +118,7 @@ export const completeDocumentWithToken = async ({
|
||||
recipientName: recipient.name,
|
||||
recipientId: recipient.id,
|
||||
recipientRole: recipient.role,
|
||||
actionAuth: derivedRecipientActionAuth || undefined,
|
||||
// actionAuth: derivedRecipientActionAuth || undefined,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
@ -79,18 +79,28 @@ export const signFieldWithToken = async ({
|
||||
throw new Error(`Field ${fieldId} has no recipientId`);
|
||||
}
|
||||
|
||||
const { derivedRecipientActionAuth } = extractDocumentAuthMethods({
|
||||
let { derivedRecipientActionAuth } = extractDocumentAuthMethods({
|
||||
documentAuth: document.authOptions,
|
||||
recipientAuth: recipient.authOptions,
|
||||
});
|
||||
|
||||
const isValid = await isRecipientAuthorized({
|
||||
type: 'ACTION',
|
||||
document: document,
|
||||
recipient: recipient,
|
||||
userId,
|
||||
authOptions,
|
||||
});
|
||||
// Override all non-signature fields to not require any auth.
|
||||
if (field.type !== FieldType.SIGNATURE) {
|
||||
derivedRecipientActionAuth = null;
|
||||
}
|
||||
|
||||
let isValid = true;
|
||||
|
||||
// Only require auth on signature fields for now.
|
||||
if (field.type === FieldType.SIGNATURE) {
|
||||
isValid = await isRecipientAuthorized({
|
||||
type: 'ACTION',
|
||||
document: document,
|
||||
recipient: recipient,
|
||||
userId,
|
||||
authOptions,
|
||||
});
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
import { hashSync } from '@documenso/lib/server-only/auth/hash';
|
||||
|
||||
import { prisma } from '..';
|
||||
|
||||
//
|
||||
// https://github.com/documenso/documenso/pull/713
|
||||
//
|
||||
|
||||
const PULL_REQUEST_NUMBER = 718;
|
||||
|
||||
const EMAIL_DOMAIN = `pr-${PULL_REQUEST_NUMBER}.documenso.com`;
|
||||
|
||||
export const TEST_USER = {
|
||||
name: 'User 1',
|
||||
email: `user1@${EMAIL_DOMAIN}`,
|
||||
password: 'Password123',
|
||||
} as const;
|
||||
|
||||
export const seedDatabase = async () => {
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
name: TEST_USER.name,
|
||||
email: TEST_USER.email,
|
||||
password: hashSync(TEST_USER.password),
|
||||
emailVerified: new Date(),
|
||||
url: TEST_USER.email,
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user