Apply prettier config to all files

This commit is contained in:
Ephraim Atta-Duncan
2023-04-04 22:02:32 +00:00
parent 85f2b5e84a
commit 84b57d715c
94 changed files with 956 additions and 1386 deletions

View File

@@ -14,10 +14,8 @@ export const createField = (
if (newFieldX < 0) newFieldX = 0;
if (newFieldY < 0) newFieldY = 0;
if (newFieldX + fieldSize.width > rect.width)
newFieldX = rect.width - fieldSize.width;
if (newFieldY + fieldSize.height > rect.height)
newFieldY = rect.height - fieldSize.height;
if (newFieldX + fieldSize.width > rect.width) newFieldX = rect.width - fieldSize.width;
if (newFieldY + fieldSize.height > rect.height) newFieldY = rect.height - fieldSize.height;
const signatureField = {
id: -1,

View File

@@ -1,6 +1,6 @@
import router from "next/router";
import toast from "react-hot-toast";
import { NEXT_PUBLIC_WEBAPP_URL } from "../lib/constants";
import toast from "react-hot-toast";
export const uploadDocument = async (event: any) => {
if (event.target.files && event.target.files[0]) {
@@ -27,9 +27,7 @@ export const uploadDocument = async (event: any) => {
)
.then((response: Response) => {
response.json().then((createdDocumentIdFromBody) => {
router.push(
`${NEXT_PUBLIC_WEBAPP_URL}/documents/${createdDocumentIdFromBody}/recipients`
);
router.push(`${NEXT_PUBLIC_WEBAPP_URL}/documents/${createdDocumentIdFromBody}/recipients`);
});
});
}

View File

@@ -6,16 +6,13 @@ export const deleteRecipient = (recipient: any) => {
}
return toast.promise(
fetch(
"/api/documents/" + recipient.documentId + "/recipients/" + recipient.id,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}
),
fetch("/api/documents/" + recipient.documentId + "/recipients/" + recipient.id, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}),
{
loading: "Deleting...",
success: "Deleted.",

View File

@@ -7,4 +7,4 @@ export { getDocuments } from "./getDocuments";
export { deleteDocument } from "./deleteDocument";
export { deleteRecipient } from "./deleteRecipient";
export { createOrUpdateRecipient } from "./createOrUpdateRecipient";
export { sendSigningRequests } from "./sendSigningRequests";
export { sendSigningRequests } from "./sendSigningRequests";

View File

@@ -1,9 +1,6 @@
import toast from "react-hot-toast";
export const sendSigningRequests = async (
document: any,
resendTo: number[] = []
) => {
export const sendSigningRequests = async (document: any, resendTo: number[] = []) => {
if (!document || !document.id) return;
try {
const sent = await toast.promise(

View File

@@ -1,11 +1,7 @@
import { useRouter } from "next/router";
import toast from "react-hot-toast";
export const signDocument = (
document: any,
signatures: any[],
token: string
): Promise<any> => {
export const signDocument = (document: any, signatures: any[], token: string): Promise<any> => {
const body = { documentId: document.id, signatures };
return toast.promise(

View File

@@ -1,12 +1,8 @@
import { compare, hash } from "bcryptjs";
import type { NextApiRequest } from "next";
import type { Session } from "next-auth";
import {
getSession as getSessionInner,
GetSessionParams,
} from "next-auth/react";
import { HttpError } from "@documenso/lib/server";
import { compare, hash } from "bcryptjs";
import type { Session } from "next-auth";
import { GetSessionParams, getSession as getSessionInner } from "next-auth/react";
export async function hashPassword(password: string) {
const hashedPassword = await hash(password, 12);
@@ -28,9 +24,7 @@ export function validPassword(password: string) {
return true;
}
export async function getSession(
options: GetSessionParams
): Promise<Session | null> {
export async function getSession(options: GetSessionParams): Promise<Session | null> {
const session = await getSessionInner(options);
// that these are equal are ensured in `[...nextauth]`'s callback
@@ -43,11 +37,7 @@ export function isPasswordValid(
breakdown: boolean,
strict?: boolean
): { caplow: boolean; num: boolean; min: boolean; admin_min: boolean };
export function isPasswordValid(
password: string,
breakdown?: boolean,
strict?: boolean
) {
export function isPasswordValid(password: string, breakdown?: boolean, strict?: boolean) {
let cap = false, // Has uppercase characters
low = false, // Has lowercase characters
num = false, // At least one number
@@ -63,8 +53,7 @@ export function isPasswordValid(
}
}
if (!breakdown)
return cap && low && num && min && (strict ? admin_min : true);
if (!breakdown) return cap && low && num && min && (strict ? admin_min : true);
let errors: Record<string, boolean> = { caplow: cap && low, num, min };
// Only return the admin key if strict mode is enabled.
@@ -73,14 +62,11 @@ export function isPasswordValid(
return errors;
}
type CtxOrReq =
| { req: NextApiRequest; ctx?: never }
| { ctx: { req: NextApiRequest }; req?: never };
type CtxOrReq = { req: NextApiRequest; ctx?: never } | { ctx: { req: NextApiRequest }; req?: never };
export const ensureSession = async (ctxOrReq: CtxOrReq) => {
const session = await getSession(ctxOrReq);
if (!session?.user)
throw new HttpError({ statusCode: 401, message: "Unauthorized" });
if (!session?.user) throw new HttpError({ statusCode: 401, message: "Unauthorized" });
return session;
};

View File

@@ -12,11 +12,7 @@ export const getSafeRedirectUrl = (url = "") => {
const urlParsed = new URL(url);
// Avoid open redirection security vulnerability
if (
!["CONSOLE_URL", "WEBAPP_URL", "WEBSITE_URL"].some(
(u) => new URL(u).origin === urlParsed.origin
)
) {
if (!["CONSOLE_URL", "WEBAPP_URL", "WEBSITE_URL"].some((u) => new URL(u).origin === urlParsed.origin)) {
url = `${"WEBAPP_URL"}/`;
}

View File

@@ -1,13 +1,9 @@
import { sendMail } from "./sendMail";
import { signingCompleteTemplate } from "@documenso/lib/mail";
import { Document as PrismaDocument } from "@prisma/client";
import { addDigitalSignature } from "@documenso/signing/addDigitalSignature";
import { sendMail } from "./sendMail";
import { Document as PrismaDocument } from "@prisma/client";
export const sendSigningDoneMail = async (
recipient: any,
document: PrismaDocument,
user: any
) => {
export const sendSigningDoneMail = async (recipient: any, document: PrismaDocument, user: any) => {
await sendMail(
user.email,
`Completed: "${document.title}"`,
@@ -15,10 +11,7 @@ export const sendSigningDoneMail = async (
[
{
filename: document.title,
content: Buffer.from(
await addDigitalSignature(document.document),
"base64"
),
content: Buffer.from(await addDigitalSignature(document.document), "base64"),
},
]
);

View File

@@ -1,8 +1,8 @@
import prisma from "@documenso/prisma";
import { sendMail } from "./sendMail";
import { SendStatus, ReadStatus, DocumentStatus } from "@prisma/client";
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
import { signingRequestTemplate } from "@documenso/lib/mail";
import prisma from "@documenso/prisma";
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
import { sendMail } from "./sendMail";
import { DocumentStatus, ReadStatus, SendStatus } from "@prisma/client";
export const sendSigningRequest = async (recipient: any, document: any, user: any) => {
const signingRequestMessage = user.name

View File

@@ -1,6 +1,6 @@
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
import { Document as PrismaDocument } from "@prisma/client";
import { baseEmailTemplate } from "./baseTemplate";
import { Document as PrismaDocument } from "@prisma/client";
export const signingCompleteTemplate = (message: string) => {
const customContent = `

View File

@@ -1,6 +1,6 @@
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
import { Document as PrismaDocument } from "@prisma/client";
import { baseEmailTemplate } from "./baseTemplate";
import { Document as PrismaDocument } from "@prisma/client";
export const signingRequestTemplate = (
message: string,

View File

@@ -2,11 +2,7 @@ import { getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { Document as PrismaDocument } from "@prisma/client";
export const getDocument = async (
documentId: number,
req: any,
res: any
): Promise<PrismaDocument> => {
export const getDocument = async (documentId: number, req: any, res: any): Promise<PrismaDocument> => {
const user = await getUserFromToken(req, res);
if (!user) return Promise.reject("Invalid user or token.");
if (!documentId) Promise.reject("No documentId");

View File

@@ -1,9 +1,7 @@
import { getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
export const getDocumentsForUserFromToken = async (
context: any
): Promise<any> => {
export const getDocumentsForUserFromToken = async (context: any): Promise<any> => {
const user = await getUserFromToken(context.req, context.res);
if (!user) return Promise.reject("Invalid user or token.");

View File

@@ -1,5 +1,4 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { getServerErrorFromUnknown } from "@documenso/lib/server";
type Handle<T> = (req: NextApiRequest, res: NextApiResponse) => Promise<T>;

View File

@@ -1,9 +1,5 @@
import {
PrismaClientKnownRequestError,
NotFoundError,
} from "@prisma/client/runtime";
import { HttpError } from "@documenso/lib/server";
import { NotFoundError, PrismaClientKnownRequestError } from "@prisma/client/runtime";
export function getServerErrorFromUnknown(cause: unknown): HttpError {
// Error was manually thrown and does not need to be parsed.

View File

@@ -1,6 +1,6 @@
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "@documenso/prisma";
import { User as PrismaUser } from "@prisma/client";
import { NextApiRequest, NextApiResponse } from "next";
import { getToken } from "next-auth/jwt";
import { signOut } from "next-auth/react";

View File

@@ -1,6 +1,6 @@
import { PDFDocument, rgb, StandardFonts } from "pdf-lib";
import fontkit from "@pdf-lib/fontkit";
import * as fs from "fs";
import { PDFDocument, StandardFonts, rgb } from "pdf-lib";
export async function insertTextInPDF(
pdfAsBase64: string,

View File

@@ -1,5 +1,5 @@
import { PrismaClient, Document, User } from "@prisma/client";
import { isENVProd } from "@documenso/lib"
import { isENVProd } from "@documenso/lib";
import { Document, PrismaClient, User } from "@prisma/client";
declare global {
var client: PrismaClient | undefined;

View File

@@ -1,7 +1,7 @@
import prisma from "@documenso/prisma";
import { hashPassword } from "@documenso/lib/auth";
import { IdentityProvider } from "@prisma/client";
import { coloredConsole } from "@documenso/lib";
import { hashPassword } from "@documenso/lib/auth";
import prisma from "@documenso/prisma";
import { IdentityProvider } from "@prisma/client";
async function createUser(userData: { email: string; password: string }) {
try {
@@ -15,9 +15,7 @@ async function createUser(userData: { email: string; password: string }) {
return user;
} catch (error) {
console.info(
`WARN: Could not create user "${userData.email}". Maybe the email is already taken?`
);
console.info(`WARN: Could not create user "${userData.email}". Maybe the email is already taken?`);
}
}

View File

@@ -1,17 +1,10 @@
import { PDFDocument, PDFHexString, PDFName, PDFNumber, PDFString } from "pdf-lib";
const fs = require("fs");
// Local copy of Node SignPDF because https://github.com/vbuch/node-signpdf/pull/187 was not published in NPM yet. Can be switched to npm packge.
const signer = require("./node-signpdf/dist/signpdf");
import {
PDFDocument,
PDFName,
PDFNumber,
PDFHexString,
PDFString,
} from "pdf-lib";
export const addDigitalSignature = async (
documentAsBase64: string
): Promise<string> => {
export const addDigitalSignature = async (documentAsBase64: string): Promise<string> => {
// Custom code to add Byterange to PDF
const PDFArrayCustom = require("./PDFArrayCustom");
const pdfBuffer = Buffer.from(documentAsBase64, "base64");

View File

@@ -1 +1 @@
export { signDocument } from "./signDocument";
export { signDocument } from "./signDocument";

View File

@@ -1,9 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = exports.ERROR_VERIFY_SIGNATURE = exports.ERROR_TYPE_UNKNOWN = exports.ERROR_TYPE_PARSE = exports.ERROR_TYPE_INPUT = void 0;
exports.default =
exports.ERROR_VERIFY_SIGNATURE =
exports.ERROR_TYPE_UNKNOWN =
exports.ERROR_TYPE_PARSE =
exports.ERROR_TYPE_INPUT =
void 0;
const ERROR_TYPE_UNKNOWN = 1;
exports.ERROR_TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN;
const ERROR_TYPE_INPUT = 2;
@@ -18,13 +23,11 @@ class SignPdfError extends Error {
super(msg);
this.type = type;
}
} // Shorthand
SignPdfError.TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN;
SignPdfError.TYPE_INPUT = ERROR_TYPE_INPUT;
SignPdfError.TYPE_PARSE = ERROR_TYPE_PARSE;
SignPdfError.VERIFY_SIGNATURE = ERROR_VERIFY_SIGNATURE;
var _default = SignPdfError;
exports.default = _default;
exports.default = _default;

View File

@@ -1,18 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.SUBFILTER_ETSI_CADES_DETACHED = exports.SUBFILTER_ADOBE_X509_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_DETACHED = exports.DEFAULT_SIGNATURE_LENGTH = exports.DEFAULT_BYTE_RANGE_PLACEHOLDER = void 0;
exports.SUBFILTER_ETSI_CADES_DETACHED =
exports.SUBFILTER_ADOBE_X509_SHA1 =
exports.SUBFILTER_ADOBE_PKCS7_SHA1 =
exports.SUBFILTER_ADOBE_PKCS7_DETACHED =
exports.DEFAULT_SIGNATURE_LENGTH =
exports.DEFAULT_BYTE_RANGE_PLACEHOLDER =
void 0;
const DEFAULT_SIGNATURE_LENGTH = 8192;
exports.DEFAULT_SIGNATURE_LENGTH = DEFAULT_SIGNATURE_LENGTH;
const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********';
const DEFAULT_BYTE_RANGE_PLACEHOLDER = "**********";
exports.DEFAULT_BYTE_RANGE_PLACEHOLDER = DEFAULT_BYTE_RANGE_PLACEHOLDER;
const SUBFILTER_ADOBE_PKCS7_DETACHED = 'adbe.pkcs7.detached';
const SUBFILTER_ADOBE_PKCS7_DETACHED = "adbe.pkcs7.detached";
exports.SUBFILTER_ADOBE_PKCS7_DETACHED = SUBFILTER_ADOBE_PKCS7_DETACHED;
const SUBFILTER_ADOBE_PKCS7_SHA1 = 'adbe.pkcs7.sha1';
const SUBFILTER_ADOBE_PKCS7_SHA1 = "adbe.pkcs7.sha1";
exports.SUBFILTER_ADOBE_PKCS7_SHA1 = SUBFILTER_ADOBE_PKCS7_SHA1;
const SUBFILTER_ADOBE_X509_SHA1 = 'adbe.x509.rsa.sha1';
const SUBFILTER_ADOBE_X509_SHA1 = "adbe.x509.rsa.sha1";
exports.SUBFILTER_ADOBE_X509_SHA1 = SUBFILTER_ADOBE_X509_SHA1;
const SUBFILTER_ETSI_CADES_DETACHED = 'ETSI.CAdES.detached';
exports.SUBFILTER_ETSI_CADES_DETACHED = SUBFILTER_ETSI_CADES_DETACHED;
const SUBFILTER_ETSI_CADES_DETACHED = "ETSI.CAdES.detached";
exports.SUBFILTER_ETSI_CADES_DETACHED = SUBFILTER_ETSI_CADES_DETACHED;

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const getSubstringIndex = (str, substring, n) => {
let times = 0;
@@ -30,42 +32,49 @@ const getSubstringIndex = (str, substring, n) => {
* @returns {Object} {ByteRange: Number[], signature: Buffer, signedData: Buffer}
*/
const extractSignature = (pdf, signatureCount = 1) => {
if (!(pdf instanceof Buffer)) {
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
} // const byteRangePos = pdf.indexOf('/ByteRange [');
const byteRangePos = getSubstringIndex(pdf, '/ByteRange [', signatureCount);
const byteRangePos = getSubstringIndex(pdf, "/ByteRange [", signatureCount);
if (byteRangePos === -1) {
throw new _SignPdfError.default('Failed to locate ByteRange.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default("Failed to locate ByteRange.", _SignPdfError.default.TYPE_PARSE);
}
const byteRangeEnd = pdf.indexOf(']', byteRangePos);
const byteRangeEnd = pdf.indexOf("]", byteRangePos);
if (byteRangeEnd === -1) {
throw new _SignPdfError.default('Failed to locate the end of the ByteRange.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
"Failed to locate the end of the ByteRange.",
_SignPdfError.default.TYPE_PARSE
);
}
const byteRange = pdf.slice(byteRangePos, byteRangeEnd + 1).toString();
const matches = /\/ByteRange \[(\d+) +(\d+) +(\d+) +(\d+) *\]/.exec(byteRange);
if (matches === null) {
throw new _SignPdfError.default('Failed to parse the ByteRange.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default("Failed to parse the ByteRange.", _SignPdfError.default.TYPE_PARSE);
}
const ByteRange = matches.slice(1).map(Number);
const signedData = Buffer.concat([pdf.slice(ByteRange[0], ByteRange[0] + ByteRange[1]), pdf.slice(ByteRange[2], ByteRange[2] + ByteRange[3])]);
const signatureHex = pdf.slice(ByteRange[0] + ByteRange[1] + 1, ByteRange[2]).toString('binary').replace(/(?:00|>)+$/, '');
const signature = Buffer.from(signatureHex, 'hex').toString('binary');
const signedData = Buffer.concat([
pdf.slice(ByteRange[0], ByteRange[0] + ByteRange[1]),
pdf.slice(ByteRange[2], ByteRange[2] + ByteRange[3]),
]);
const signatureHex = pdf
.slice(ByteRange[0] + ByteRange[1] + 1, ByteRange[2])
.toString("binary")
.replace(/(?:00|>)+$/, "");
const signature = Buffer.from(signatureHex, "hex").toString("binary");
return {
ByteRange: matches.slice(1, 5).map(Number),
signature,
signedData
signedData,
};
};
var _default = extractSignature;
exports.default = _default;
exports.default = _default;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -9,7 +9,9 @@ var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
var _const = require("./const");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/**
* Finds ByteRange information within a given PDF Buffer if one exists
@@ -17,25 +19,32 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
* @param {Buffer} pdf
* @returns {Object} {byteRangePlaceholder: String, byteRangeStrings: String[], byteRange: String[]}
*/
const findByteRange = pdf => {
const findByteRange = (pdf) => {
if (!(pdf instanceof Buffer)) {
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
}
const byteRangeStrings = pdf.toString().match(/\/ByteRange\s*\[{1}\s*(?:(?:\d*|\/\*{10})\s+){3}(?:\d+|\/\*{10}){1}\s*]{1}/g);
const byteRangeStrings = pdf
.toString()
.match(/\/ByteRange\s*\[{1}\s*(?:(?:\d*|\/\*{10})\s+){3}(?:\d+|\/\*{10}){1}\s*]{1}/g);
if (!byteRangeStrings) {
throw new _SignPdfError.default('No ByteRangeStrings found within PDF buffer', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
"No ByteRangeStrings found within PDF buffer",
_SignPdfError.default.TYPE_PARSE
);
}
const byteRangePlaceholder = byteRangeStrings.find(s => s.includes(`/${_const.DEFAULT_BYTE_RANGE_PLACEHOLDER}`));
const byteRanges = byteRangeStrings.map(brs => brs.match(/[^[\s]*(?:\d|\/\*{10})/g));
const byteRangePlaceholder = byteRangeStrings.find((s) =>
s.includes(`/${_const.DEFAULT_BYTE_RANGE_PLACEHOLDER}`)
);
const byteRanges = byteRangeStrings.map((brs) => brs.match(/[^[\s]*(?:\d|\/\*{10})/g));
return {
byteRangePlaceholder,
byteRangeStrings,
byteRanges
byteRanges,
};
};
var _default = findByteRange;
exports.default = _default;
exports.default = _default;

View File

@@ -1,37 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
Object.defineProperty(exports, "extractSignature", {
enumerable: true,
get: function () {
return _extractSignature.default;
}
},
});
Object.defineProperty(exports, "findByteRange", {
enumerable: true,
get: function () {
return _findByteRange.default;
}
},
});
Object.defineProperty(exports, "pdfkitAddPlaceholder", {
enumerable: true,
get: function () {
return _pdfkitAddPlaceholder.default;
}
},
});
Object.defineProperty(exports, "plainAddPlaceholder", {
enumerable: true,
get: function () {
return _plainAddPlaceholder.default;
}
},
});
Object.defineProperty(exports, "removeTrailingNewLine", {
enumerable: true,
get: function () {
return _removeTrailingNewLine.default;
}
},
});
var _extractSignature = _interopRequireDefault(require("./extractSignature"));
@@ -44,6 +44,8 @@ var _removeTrailingNewLine = _interopRequireDefault(require("./removeTrailingNew
var _findByteRange = _interopRequireDefault(require("./findByteRange"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
'This string is added so that jest collects coverage for this file'; // eslint-disable-line
("This string is added so that jest collects coverage for this file"); // eslint-disable-line

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -17,10 +17,9 @@ PDFAbstractReference - abstract class for PDF reference
*/
class PDFAbstractReference {
toString() {
throw new Error('Must be implemented by subclasses');
throw new Error("Must be implemented by subclasses");
}
}
var _default = PDFAbstractReference;
exports.default = _default;
exports.default = _default;

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _abstract_reference = _interopRequireDefault(require("./abstract_reference"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/*
PDFObject by Devon Govett used below.
@@ -20,26 +22,26 @@ Modifications may have been applied for the purposes of node-signpdf.
PDFObject - converts JavaScript types into their corresponding PDF types.
By Devon Govett
*/
const pad = (str, length) => (Array(length + 1).join('0') + str).slice(-length);
const pad = (str, length) => (Array(length + 1).join("0") + str).slice(-length);
const escapableRe = /[\n\r\t\b\f()\\]/g;
const escapable = {
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
'\b': '\\b',
'\f': '\\f',
'\\': '\\\\',
'(': '\\(',
')': '\\)'
"\n": "\\n",
"\r": "\\r",
"\t": "\\t",
"\b": "\\b",
"\f": "\\f",
"\\": "\\\\",
"(": "\\(",
")": "\\)",
}; // Convert little endian UTF-16 to big endian
const swapBytes = buff => buff.swap16();
const swapBytes = (buff) => buff.swap16();
class PDFObject {
static convert(object, encryptFn = null) {
// String literals are converted to the PDF name type
if (typeof object === 'string') {
if (typeof object === "string") {
return `/${object}`; // String objects are converted to PDF strings (UTF-16)
}
@@ -55,29 +57,26 @@ class PDFObject {
}
} // If so, encode it as big endian UTF-16
let stringBuffer;
if (isUnicode) {
stringBuffer = swapBytes(Buffer.from(`\ufeff${string}`, 'utf16le'));
stringBuffer = swapBytes(Buffer.from(`\ufeff${string}`, "utf16le"));
} else {
stringBuffer = Buffer.from(string, 'ascii');
stringBuffer = Buffer.from(string, "ascii");
} // Encrypt the string when necessary
if (encryptFn) {
string = encryptFn(stringBuffer).toString('binary');
string = encryptFn(stringBuffer).toString("binary");
} else {
string = stringBuffer.toString('binary');
string = stringBuffer.toString("binary");
} // Escape characters as required by the spec
string = string.replace(escapableRe, c => escapable[c]);
string = string.replace(escapableRe, (c) => escapable[c]);
return `(${string})`; // Buffers are converted to PDF hex strings
}
if (Buffer.isBuffer(object)) {
return `<${object.toString('hex')}>`;
return `<${object.toString("hex")}>`;
}
if (object instanceof _abstract_reference.default) {
@@ -85,51 +84,54 @@ class PDFObject {
}
if (object instanceof Date) {
let string = `D:${pad(object.getUTCFullYear(), 4)}${pad(object.getUTCMonth() + 1, 2)}${pad(object.getUTCDate(), 2)}${pad(object.getUTCHours(), 2)}${pad(object.getUTCMinutes(), 2)}${pad(object.getUTCSeconds(), 2)}Z`; // Encrypt the string when necessary
let string = `D:${pad(object.getUTCFullYear(), 4)}${pad(object.getUTCMonth() + 1, 2)}${pad(
object.getUTCDate(),
2
)}${pad(object.getUTCHours(), 2)}${pad(object.getUTCMinutes(), 2)}${pad(object.getUTCSeconds(), 2)}Z`; // Encrypt the string when necessary
if (encryptFn) {
string = encryptFn(Buffer.from(string, 'ascii')).toString('binary'); // Escape characters as required by the spec
string = encryptFn(Buffer.from(string, "ascii")).toString("binary"); // Escape characters as required by the spec
string = string.replace(escapableRe, c => escapable[c]);
string = string.replace(escapableRe, (c) => escapable[c]);
}
return `(${string})`;
}
if (Array.isArray(object)) {
const items = object.map(e => PDFObject.convert(e, encryptFn)).join(' ');
const items = object.map((e) => PDFObject.convert(e, encryptFn)).join(" ");
return `[${items}]`;
}
if ({}.toString.call(object) === '[object Object]') {
const out = ['<<'];
if ({}.toString.call(object) === "[object Object]") {
const out = ["<<"];
let streamData; // @todo this can probably be refactored into a reduce
Object.entries(object).forEach(([key, val]) => {
let checkedValue = '';
let checkedValue = "";
if (val.toString().indexOf('<<') !== -1) {
if (val.toString().indexOf("<<") !== -1) {
checkedValue = val;
} else {
checkedValue = PDFObject.convert(val, encryptFn);
}
if (key === 'stream') {
if (key === "stream") {
streamData = `${key}\n${val}\nendstream`;
} else {
out.push(`/${key} ${checkedValue}`);
}
});
out.push('>>');
out.push(">>");
if (streamData) {
out.push(streamData);
}
return out.join('\n');
return out.join("\n");
}
if (typeof object === 'number') {
if (typeof object === "number") {
return PDFObject.number(object);
}
@@ -143,7 +145,6 @@ class PDFObject {
throw new Error(`unsupported number: ${n}`);
}
}
exports.default = PDFObject;
exports.default = PDFObject;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -9,7 +9,9 @@ var _const = require("./const");
var _pdfkitReferenceMock = _interopRequireDefault(require("./pdfkitReferenceMock"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
// eslint-disable-next-line import/no-unresolved
@@ -25,18 +27,18 @@ const pdfkitAddPlaceholder = ({
pdf,
pdfBuffer,
reason,
contactInfo = 'emailfromp1289@gmail.com',
name = 'Name from p12',
location = 'Location from p12',
contactInfo = "emailfromp1289@gmail.com",
name = "Name from p12",
location = "Location from p12",
signatureLength = _const.DEFAULT_SIGNATURE_LENGTH,
byteRangePlaceholder = _const.DEFAULT_BYTE_RANGE_PLACEHOLDER,
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED,
}) => {
/* eslint-disable no-underscore-dangle,no-param-reassign */
// Generate the signature placeholder
const signature = pdf.ref({
Type: 'Sig',
Filter: 'Adobe.PPKLite',
Type: "Sig",
Filter: "Adobe.PPKLite",
SubFilter: subFilter,
ByteRange: [0, byteRangePlaceholder, byteRangePlaceholder, byteRangePlaceholder],
Contents: Buffer.from(String.fromCharCode(0).repeat(signatureLength)),
@@ -47,11 +49,10 @@ const pdfkitAddPlaceholder = ({
// eslint-disable-line no-new-wrappers
Name: new String(name),
// eslint-disable-line no-new-wrappers
Location: new String(location) // eslint-disable-line no-new-wrappers
Location: new String(location), // eslint-disable-line no-new-wrappers
}); // Check if pdf already contains acroform field
const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
const acroFormPosition = pdfBuffer.lastIndexOf("/Type /AcroForm");
const isAcroFormExists = acroFormPosition !== -1;
let fieldIds = [];
let acroFormId;
@@ -65,13 +66,13 @@ const pdfkitAddPlaceholder = ({
// (generally it's 2 or 3, but I'm giving a big space though)
const maxAcroFormIdLength = 12;
let foundAcroFormId = '';
let foundAcroFormId = "";
let index = charsUntilIdEnd + 1;
for (index; index < charsUntilIdEnd + maxAcroFormIdLength; index += 1) {
const acroFormIdString = pdfBuffer.slice(acroFormPosition - index, acroFormIdEnd).toString();
if (acroFormIdString[0] === '\n') {
if (acroFormIdString[0] === "\n") {
break;
}
@@ -80,25 +81,27 @@ const pdfkitAddPlaceholder = ({
}
const pdfSlice = pdfBuffer.slice(acroFormStart);
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf('endobj')).toString();
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf("endobj")).toString();
acroFormId = parseInt(foundAcroFormId);
const acroFormFields = acroForm.slice(acroForm.indexOf('/Fields [') + 9, acroForm.indexOf(']'));
fieldIds = acroFormFields.split(' ').filter((element, i) => i % 3 === 0).map(fieldId => new _pdfkitReferenceMock.default(fieldId));
const acroFormFields = acroForm.slice(acroForm.indexOf("/Fields [") + 9, acroForm.indexOf("]"));
fieldIds = acroFormFields
.split(" ")
.filter((element, i) => i % 3 === 0)
.map((fieldId) => new _pdfkitReferenceMock.default(fieldId));
}
const signatureName = 'Signature'; // Generate signature annotation widget
const signatureName = "Signature"; // Generate signature annotation widget
const widget = pdf.ref({
Type: 'Annot',
Subtype: 'Widget',
FT: 'Sig',
Type: "Annot",
Subtype: "Widget",
FT: "Sig",
Rect: [0, 0, 0, 0],
V: signature,
T: new String(signatureName + (fieldIds.length + 1)),
// eslint-disable-line no-new-wrappers
F: 4,
P: pdf.page.dictionary // eslint-disable-line no-underscore-dangle
P: pdf.page.dictionary, // eslint-disable-line no-underscore-dangle
});
pdf.page.dictionary.data.Annots = [widget]; // Include the widget in a page
@@ -107,27 +110,30 @@ const pdfkitAddPlaceholder = ({
if (!isAcroFormExists) {
// Create a form (with the widget) and link in the _root
form = pdf.ref({
Type: 'AcroForm',
Type: "AcroForm",
SigFlags: 3,
Fields: [...fieldIds, widget]
Fields: [...fieldIds, widget],
});
} else {
// Use existing acroform and extend the fields with newly created widgets
form = pdf.ref({
Type: 'AcroForm',
SigFlags: 3,
Fields: [...fieldIds, widget]
}, acroFormId);
form = pdf.ref(
{
Type: "AcroForm",
SigFlags: 3,
Fields: [...fieldIds, widget],
},
acroFormId
);
}
pdf._root.data.AcroForm = form;
return {
signature,
form,
widget
widget,
};
/* eslint-enable no-underscore-dangle,no-param-reassign */
};
var _default = pdfkitAddPlaceholder;
exports.default = _default;
exports.default = _default;

View File

@@ -1,20 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _abstract_reference = _interopRequireDefault(require("./pdfkit/abstract_reference"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
class PDFKitReferenceMock extends _abstract_reference.default {
constructor(index, additionalData = undefined) {
super();
this.index = index;
if (typeof additionalData !== 'undefined') {
if (typeof additionalData !== "undefined") {
Object.assign(this, additionalData);
}
}
@@ -22,8 +24,7 @@ class PDFKitReferenceMock extends _abstract_reference.default {
toString() {
return `${this.index} 0 R`;
}
}
var _default = PDFKitReferenceMock;
exports.default = _default;
exports.default = _default;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -9,7 +9,9 @@ var _findObject = _interopRequireDefault(require("./findObject"));
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
const pagesDictionary = (0, _findObject.default)(pdf, info.xref, pagesRef).toString(); // Extend page dictionary with newly created annotations
@@ -17,16 +19,16 @@ const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
let annotsStart;
let annotsEnd;
let annots;
annotsStart = pagesDictionary.indexOf('/Annots');
annotsStart = pagesDictionary.indexOf("/Annots");
if (annotsStart > -1) {
annotsEnd = pagesDictionary.indexOf(']', annotsStart);
annotsEnd = pagesDictionary.indexOf("]", annotsStart);
annots = pagesDictionary.substr(annotsStart, annotsEnd + 1 - annotsStart);
annots = annots.substr(0, annots.length - 1); // remove the trailing ]
} else {
annotsStart = pagesDictionary.length;
annotsEnd = pagesDictionary.length;
annots = '/Annots [';
annots = "/Annots [";
}
const pagesDictionaryIndex = (0, _getIndexFromRef.default)(info.xref, pagesRef);
@@ -34,14 +36,19 @@ const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
annots = `${annots} ${widgetValue}]`; // add the trailing ] back
const preAnnots = pagesDictionary.substr(0, annotsStart);
let postAnnots = '';
let postAnnots = "";
if (pagesDictionary.length > annotsEnd) {
postAnnots = pagesDictionary.substr(annotsEnd + 1);
}
return Buffer.concat([Buffer.from(`${pagesDictionaryIndex} 0 obj\n`), Buffer.from('<<\n'), Buffer.from(`${preAnnots + annots + postAnnots}\n`), Buffer.from('\n>>\nendobj\n')]);
return Buffer.concat([
Buffer.from(`${pagesDictionaryIndex} 0 obj\n`),
Buffer.from("<<\n"),
Buffer.from(`${preAnnots + annots + postAnnots}\n`),
Buffer.from("\n>>\nendobj\n"),
]);
};
var _default = createBufferPageWithAnnotation;
exports.default = _default;
exports.default = _default;

View File

@@ -1,18 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const createBufferRootWithAcroform = (pdf, info, form) => {
const rootIndex = (0, _getIndexFromRef.default)(info.xref, info.rootRef);
return Buffer.concat([Buffer.from(`${rootIndex} 0 obj\n`), Buffer.from('<<\n'), Buffer.from(`${info.root}\n`), Buffer.from(`/AcroForm ${form}`), Buffer.from('\n>>\nendobj\n')]);
return Buffer.concat([
Buffer.from(`${rootIndex} 0 obj\n`),
Buffer.from("<<\n"),
Buffer.from(`${info.root}\n`),
Buffer.from(`/AcroForm ${form}`),
Buffer.from("\n>>\nendobj\n"),
]);
};
var _default = createBufferRootWithAcroform;
exports.default = _default;
exports.default = _default;

View File

@@ -1,21 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
const createBufferTrailer = (pdf, info, addedReferences) => {
let rows = [];
rows[0] = '0000000000 65535 f '; // info.xref.tableRows[0];
rows[0] = "0000000000 65535 f "; // info.xref.tableRows[0];
addedReferences.forEach((offset, index) => {
const paddedOffset = `0000000000${offset}`.slice(-10);
rows[index + 1] = `${index} 1\n${paddedOffset} 00000 n `;
});
rows = rows.filter(row => row !== undefined);
return Buffer.concat([Buffer.from('xref\n'), Buffer.from(`${info.xref.startingIndex} 1\n`), Buffer.from(rows.join('\n')), Buffer.from('\ntrailer\n'), Buffer.from('<<\n'), Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`), Buffer.from(`/Root ${info.rootRef}\n`), Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ''), Buffer.from(`/Prev ${info.xRefPosition}\n`), Buffer.from('>>\n'), Buffer.from('startxref\n'), Buffer.from(`${pdf.length}\n`), Buffer.from('%%EOF')]);
rows = rows.filter((row) => row !== undefined);
return Buffer.concat([
Buffer.from("xref\n"),
Buffer.from(`${info.xref.startingIndex} 1\n`),
Buffer.from(rows.join("\n")),
Buffer.from("\ntrailer\n"),
Buffer.from("<<\n"),
Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`),
Buffer.from(`/Root ${info.rootRef}\n`),
Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ""),
Buffer.from(`/Prev ${info.xRefPosition}\n`),
Buffer.from(">>\n"),
Buffer.from("startxref\n"),
Buffer.from(`${pdf.length}\n`),
Buffer.from("%%EOF"),
]);
};
var _default = createBufferTrailer;
exports.default = _default;
exports.default = _default;

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/**
* @param {Buffer} pdf
@@ -18,12 +20,12 @@ const findObject = (pdf, refTable, ref) => {
const index = (0, _getIndexFromRef.default)(refTable, ref);
const offset = refTable.offsets.get(index);
let slice = pdf.slice(offset);
slice = slice.slice(0, slice.indexOf('endobj', 'utf8')); // FIXME: What if it is a stream?
slice = slice.slice(0, slice.indexOf("endobj", "utf8")); // FIXME: What if it is a stream?
slice = slice.slice(slice.indexOf('<<', 'utf8') + 2);
slice = slice.slice(0, slice.lastIndexOf('>>', 'utf8'));
slice = slice.slice(slice.indexOf("<<", "utf8") + 2);
slice = slice.slice(0, slice.lastIndexOf(">>", "utf8"));
return slice;
};
var _default = findObject;
exports.default = _default;
exports.default = _default;

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/**
* @param {object} refTable
@@ -15,7 +17,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
* @returns {number}
*/
const getIndexFromRef = (refTable, ref) => {
let [index] = ref.split(' ');
let [index] = ref.split(" ");
index = parseInt(index);
if (!refTable.offsets.has(index)) {
@@ -26,4 +28,4 @@ const getIndexFromRef = (refTable, ref) => {
};
var _default = getIndexFromRef;
exports.default = _default;
exports.default = _default;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = getPageRef;
@@ -9,7 +9,9 @@ var _getPagesDictionaryRef = _interopRequireDefault(require("./getPagesDictionar
var _findObject = _interopRequireDefault(require("./findObject"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/**
* Finds the reference to a page.
@@ -20,10 +22,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
function getPageRef(pdfBuffer, info) {
const pagesRef = (0, _getPagesDictionaryRef.default)(info);
const pagesDictionary = (0, _findObject.default)(pdfBuffer, info.xref, pagesRef);
const kidsPosition = pagesDictionary.indexOf('/Kids');
const kidsStart = pagesDictionary.indexOf('[', kidsPosition) + 1;
const kidsEnd = pagesDictionary.indexOf(']', kidsPosition);
const kidsPosition = pagesDictionary.indexOf("/Kids");
const kidsStart = pagesDictionary.indexOf("[", kidsPosition) + 1;
const kidsEnd = pagesDictionary.indexOf("]", kidsPosition);
const pages = pagesDictionary.slice(kidsStart, kidsEnd).toString();
const split = pages.trim().split(' ', 3);
const split = pages.trim().split(" ", 3);
return `${split[0]} ${split[1]} ${split[2]}`;
}
}

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = getPagesDictionaryRef;
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
/**
* @param {Object} info As extracted from readRef()
@@ -17,8 +19,11 @@ function getPagesDictionaryRef(info) {
const match = pagesRefRegex.exec(info.root);
if (match === null) {
throw new _SignPdfError.default('Failed to find the pages descriptor. This is probably a problem in node-signpdf.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
"Failed to find the pages descriptor. This is probably a problem in node-signpdf.",
_SignPdfError.default.TYPE_PARSE
);
}
return match[1];
}
}

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -27,12 +27,14 @@ var _createBufferPageWithAnnotation = _interopRequireDefault(require("./createBu
var _createBufferTrailer = _interopRequireDefault(require("./createBufferTrailer"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const isContainBufferRootWithAcroform = pdf => {
const isContainBufferRootWithAcroform = (pdf) => {
const bufferRootWithAcroformRefRegex = /\/AcroForm\s+(\d+\s\d+\sR)/g;
const match = bufferRootWithAcroformRefRegex.exec(pdf.toString());
return match != null && match[1] != null && match[1] !== '';
return match != null && match[1] != null && match[1] !== "";
};
/**
* Adds a signature placeholder to a PDF Buffer.
@@ -44,15 +46,14 @@ const isContainBufferRootWithAcroform = pdf => {
* not only on a freshly created through PDFKit one.
*/
const plainAddPlaceholder = ({
pdfBuffer,
reason,
contactInfo = 'emailfromp1289@gmail.com',
name = 'Name from p12',
location = 'Location from p12',
contactInfo = "emailfromp1289@gmail.com",
name = "Name from p12",
location = "Location from p12",
signatureLength = _const.DEFAULT_SIGNATURE_LENGTH,
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED,
}) => {
let pdf = (0, _removeTrailingNewLine.default)(pdfBuffer);
const info = (0, _readPdf.default)(pdf);
@@ -65,24 +66,27 @@ const plainAddPlaceholder = ({
const index = additionalIndex != null ? additionalIndex : info.xref.maxIndex;
addedReferences.set(index, pdf.length + 1); // + 1 new line
pdf = Buffer.concat([pdf, Buffer.from('\n'), Buffer.from(`${index} 0 obj\n`), Buffer.from(_pdfobject.default.convert(input)), Buffer.from('\nendobj\n')]);
pdf = Buffer.concat([
pdf,
Buffer.from("\n"),
Buffer.from(`${index} 0 obj\n`),
Buffer.from(_pdfobject.default.convert(input)),
Buffer.from("\nendobj\n"),
]);
return new _pdfkitReferenceMock.default(info.xref.maxIndex);
},
page: {
dictionary: new _pdfkitReferenceMock.default(pageIndex, {
data: {
Annots: []
}
})
Annots: [],
},
}),
},
_root: {
data: {}
}
data: {},
},
};
const {
form,
widget
} = (0, _pdfkitAddPlaceholder.default)({
const { form, widget } = (0, _pdfkitAddPlaceholder.default)({
pdf: pdfKitMock,
pdfBuffer,
reason,
@@ -90,20 +94,32 @@ const plainAddPlaceholder = ({
name,
location,
signatureLength,
subFilter
subFilter,
});
if (!isContainBufferRootWithAcroform(pdf)) {
const rootIndex = (0, _getIndexFromRef.default)(info.xref, info.rootRef);
addedReferences.set(rootIndex, pdf.length + 1);
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferRootWithAcroform.default)(pdf, info, form)]);
pdf = Buffer.concat([
pdf,
Buffer.from("\n"),
(0, _createBufferRootWithAcroform.default)(pdf, info, form),
]);
}
addedReferences.set(pageIndex, pdf.length + 1);
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferPageWithAnnotation.default)(pdf, info, pageRef, widget)]);
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferTrailer.default)(pdf, info, addedReferences)]);
pdf = Buffer.concat([
pdf,
Buffer.from("\n"),
(0, _createBufferPageWithAnnotation.default)(pdf, info, pageRef, widget),
]);
pdf = Buffer.concat([
pdf,
Buffer.from("\n"),
(0, _createBufferTrailer.default)(pdf, info, addedReferences),
]);
return pdf;
};
var _default = plainAddPlaceholder;
exports.default = _default;
exports.default = _default;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
@@ -9,7 +9,9 @@ var _readRefTable = _interopRequireDefault(require("./readRefTable"));
var _findObject = _interopRequireDefault(require("./findObject"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const getValue = (trailer, key) => {
let index = trailer.indexOf(key);
@@ -19,13 +21,16 @@ const getValue = (trailer, key) => {
}
const slice = trailer.slice(index);
index = slice.indexOf('/', 1);
index = slice.indexOf("/", 1);
if (index === -1) {
index = slice.indexOf('>', 1);
index = slice.indexOf(">", 1);
}
return slice.slice(key.length + 1, index).toString().trim(); // key + at least one space
return slice
.slice(key.length + 1, index)
.toString()
.trim(); // key + at least one space
};
/**
* Simplified parsing of a PDF Buffer.
@@ -36,18 +41,17 @@ const getValue = (trailer, key) => {
* @param {Buffer} pdfBuffer
*/
const readPdf = pdfBuffer => {
const readPdf = (pdfBuffer) => {
// Extract the trailer dictionary.
const trailerStart = pdfBuffer.lastIndexOf('trailer'); // The trailer is followed by xref. Then an EOF. EOF's length is 6 characters.
const trailerStart = pdfBuffer.lastIndexOf("trailer"); // The trailer is followed by xref. Then an EOF. EOF's length is 6 characters.
const trailer = pdfBuffer.slice(trailerStart, pdfBuffer.length - 6);
let xRefPosition = trailer.slice(trailer.lastIndexOf('startxref') + 10).toString();
let xRefPosition = trailer.slice(trailer.lastIndexOf("startxref") + 10).toString();
xRefPosition = parseInt(xRefPosition);
const refTable = (0, _readRefTable.default)(pdfBuffer);
const rootRef = getValue(trailer, '/Root');
const rootRef = getValue(trailer, "/Root");
const root = (0, _findObject.default)(pdfBuffer, refTable, rootRef).toString();
const infoRef = getValue(trailer, '/Info');
const infoRef = getValue(trailer, "/Info");
return {
xref: refTable,
rootRef,
@@ -55,9 +59,9 @@ const readPdf = pdfBuffer => {
infoRef,
trailerStart,
previousXrefs: [],
xRefPosition
xRefPosition,
};
};
var _default = readPdf;
exports.default = _default;
exports.default = _default;

View File

@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.getXref = exports.getLastTrailerPosition = exports.getFullXrefTable = exports.default = void 0;
@@ -9,12 +9,14 @@ var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
var _xrefToRefMap = _interopRequireDefault(require("./xrefToRefMap"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const getLastTrailerPosition = pdf => {
const trailerStart = pdf.lastIndexOf(Buffer.from('trailer', 'utf8'));
const getLastTrailerPosition = (pdf) => {
const trailerStart = pdf.lastIndexOf(Buffer.from("trailer", "utf8"));
const trailer = pdf.slice(trailerStart, pdf.length - 6);
const xRefPosition = trailer.slice(trailer.lastIndexOf(Buffer.from('startxref', 'utf8')) + 10).toString();
const xRefPosition = trailer.slice(trailer.lastIndexOf(Buffer.from("startxref", "utf8")) + 10).toString();
return parseInt(xRefPosition);
};
@@ -23,47 +25,56 @@ exports.getLastTrailerPosition = getLastTrailerPosition;
const getXref = (pdf, position) => {
let refTable = pdf.slice(position); // slice starting from where xref starts
const realPosition = refTable.indexOf(Buffer.from('xref', 'utf8'));
const realPosition = refTable.indexOf(Buffer.from("xref", "utf8"));
if (realPosition === -1) {
throw new _SignPdfError.default(`Could not find xref anywhere at or after ${position}.`, _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
`Could not find xref anywhere at or after ${position}.`,
_SignPdfError.default.TYPE_PARSE
);
}
if (realPosition > 0) {
const prefix = refTable.slice(0, realPosition);
if (prefix.toString().replace(/\s*/g, '') !== '') {
throw new _SignPdfError.default(`Expected xref at ${position} but found other content.`, _SignPdfError.default.TYPE_PARSE);
if (prefix.toString().replace(/\s*/g, "") !== "") {
throw new _SignPdfError.default(
`Expected xref at ${position} but found other content.`,
_SignPdfError.default.TYPE_PARSE
);
}
}
const nextEofPosition = refTable.indexOf(Buffer.from('%%EOF', 'utf8'));
const nextEofPosition = refTable.indexOf(Buffer.from("%%EOF", "utf8"));
if (nextEofPosition === -1) {
throw new _SignPdfError.default('Expected EOF after xref and trailer but could not find one.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
"Expected EOF after xref and trailer but could not find one.",
_SignPdfError.default.TYPE_PARSE
);
}
refTable = refTable.slice(0, nextEofPosition);
refTable = refTable.slice(realPosition + 4); // move ahead with the "xref"
refTable = refTable.slice(refTable.indexOf('\n') + 1); // move after the next new line
refTable = refTable.slice(refTable.indexOf("\n") + 1); // move after the next new line
// extract the size
let size = refTable.toString().split('/Size')[1];
let size = refTable.toString().split("/Size")[1];
if (!size) {
throw new _SignPdfError.default('Size not found in xref table.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default("Size not found in xref table.", _SignPdfError.default.TYPE_PARSE);
}
size = /^\s*(\d+)/.exec(size);
if (size === null) {
throw new _SignPdfError.default('Failed to parse size of xref table.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default("Failed to parse size of xref table.", _SignPdfError.default.TYPE_PARSE);
}
size = parseInt(size[1]);
const [objects, infos] = refTable.toString().split('trailer');
const isContainingPrev = infos.split('/Prev')[1] != null;
const [objects, infos] = refTable.toString().split("trailer");
const isContainingPrev = infos.split("/Prev")[1] != null;
let prev;
if (isContainingPrev) {
@@ -77,13 +88,13 @@ const getXref = (pdf, position) => {
return {
size,
prev,
xRefContent
xRefContent,
};
};
exports.getXref = getXref;
const getFullXrefTable = pdf => {
const getFullXrefTable = (pdf) => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
const lastXrefTable = getXref(pdf, lastTrailerPosition);
@@ -101,19 +112,18 @@ const getFullXrefTable = pdf => {
* @returns {object}
*/
exports.getFullXrefTable = getFullXrefTable;
const readRefTable = pdf => {
const readRefTable = (pdf) => {
const fullXrefTable = getFullXrefTable(pdf);
const startingIndex = 0;
const maxIndex = Math.max(...fullXrefTable.keys());
return {
startingIndex,
maxIndex,
offsets: fullXrefTable
offsets: fullXrefTable,
};
};
var _default = readRefTable;
exports.default = _default;
exports.default = _default;

View File

@@ -1,21 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const xrefToRefMap = xrefString => {
const lines = xrefString.split('\n').filter(l => l !== '');
const xrefToRefMap = (xrefString) => {
const lines = xrefString.split("\n").filter((l) => l !== "");
let index = 0;
let expectedLines = 0;
const xref = new Map();
lines.forEach(line => {
const split = line.split(' ');
lines.forEach((line) => {
const split = line.split(" ");
if (split.length === 2) {
index = parseInt(split[0]);
@@ -24,23 +26,29 @@ const xrefToRefMap = xrefString => {
}
if (expectedLines <= 0) {
throw new _SignPdfError.default('Too many lines in xref table.', _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default("Too many lines in xref table.", _SignPdfError.default.TYPE_PARSE);
}
expectedLines -= 1;
const [offset,, inUse] = split;
const [offset, , inUse] = split;
if (inUse.trim() === 'f') {
if (inUse.trim() === "f") {
index += 1;
return;
}
if (inUse.trim() !== 'n') {
throw new _SignPdfError.default(`Unknown in-use flag "${inUse}". Expected "n" or "f".`, _SignPdfError.default.TYPE_PARSE);
if (inUse.trim() !== "n") {
throw new _SignPdfError.default(
`Unknown in-use flag "${inUse}". Expected "n" or "f".`,
_SignPdfError.default.TYPE_PARSE
);
}
if (!/^\d+$/.test(offset.trim())) {
throw new _SignPdfError.default(`Expected integer offset. Got "${offset}".`, _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
`Expected integer offset. Got "${offset}".`,
_SignPdfError.default.TYPE_PARSE
);
}
const storeOffset = parseInt(offset.trim());
@@ -51,4 +59,4 @@ const xrefToRefMap = xrefString => {
};
var _default = xrefToRefMap;
exports.default = _default;
exports.default = _default;

View File

@@ -1,13 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
exports.default = void 0;
var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
const sliceLastChar = (pdf, character) => {
const lastChar = pdf.slice(pdf.length - 1).toString();
@@ -26,23 +28,25 @@ const sliceLastChar = (pdf, character) => {
* @returns {Buffer}
*/
const removeTrailingNewLine = pdf => {
const removeTrailingNewLine = (pdf) => {
if (!(pdf instanceof Buffer)) {
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
}
let output = pdf;
output = sliceLastChar(output, '\n');
output = sliceLastChar(output, '\r');
output = sliceLastChar(output, "\n");
output = sliceLastChar(output, "\r");
const lastLine = output.slice(output.length - 6).toString();
if (lastLine !== '\n%%EOF') {
throw new _SignPdfError.default('A PDF file must end with an EOF line.', _SignPdfError.default.TYPE_PARSE);
if (lastLine !== "\n%%EOF") {
throw new _SignPdfError.default(
"A PDF file must end with an EOF line.",
_SignPdfError.default.TYPE_PARSE
);
}
return output;
};
var _default = removeTrailingNewLine;
exports.default = _default;
exports.default = _default;

View File

@@ -1,18 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true,
});
var _exportNames = {
SignPdf: true,
SignPdfError: true
SignPdfError: true,
};
exports.SignPdf = void 0;
Object.defineProperty(exports, "SignPdfError", {
enumerable: true,
get: function () {
return _SignPdfError.default;
}
},
});
exports.default = void 0;
@@ -30,7 +30,7 @@ Object.keys(_helpers).forEach(function (key) {
enumerable: true,
get: function () {
return _helpers[key];
}
},
});
});
@@ -44,11 +44,13 @@ Object.keys(_const).forEach(function (key) {
enumerable: true,
get: function () {
return _const[key];
}
},
});
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
class SignPdf {
constructor() {
@@ -59,77 +61,81 @@ class SignPdf {
sign(pdfBuffer, p12Buffer, additionalOptions = {}) {
const options = {
asn1StrictParsing: false,
passphrase: '',
...additionalOptions
passphrase: "",
...additionalOptions,
};
if (!(pdfBuffer instanceof Buffer)) {
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
}
if (!(p12Buffer instanceof Buffer)) {
throw new _SignPdfError.default('p12 certificate expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default(
"p12 certificate expected as Buffer.",
_SignPdfError.default.TYPE_INPUT
);
}
let pdf = (0, _helpers.removeTrailingNewLine)(pdfBuffer); // Find the ByteRange placeholder.
const {
byteRangePlaceholder
} = (0, _helpers.findByteRange)(pdf);
const { byteRangePlaceholder } = (0, _helpers.findByteRange)(pdf);
if (!byteRangePlaceholder) {
throw new _SignPdfError.default(`Could not find empty ByteRange placeholder: ${byteRangePlaceholder}`, _SignPdfError.default.TYPE_PARSE);
throw new _SignPdfError.default(
`Could not find empty ByteRange placeholder: ${byteRangePlaceholder}`,
_SignPdfError.default.TYPE_PARSE
);
}
const byteRangePos = pdf.indexOf(byteRangePlaceholder); // Calculate the actual ByteRange that needs to replace the placeholder.
const byteRangeEnd = byteRangePos + byteRangePlaceholder.length;
const contentsTagPos = pdf.indexOf('/Contents ', byteRangeEnd);
const placeholderPos = pdf.indexOf('<', contentsTagPos);
const placeholderEnd = pdf.indexOf('>', placeholderPos);
const contentsTagPos = pdf.indexOf("/Contents ", byteRangeEnd);
const placeholderPos = pdf.indexOf("<", contentsTagPos);
const placeholderEnd = pdf.indexOf(">", placeholderPos);
const placeholderLengthWithBrackets = placeholderEnd + 1 - placeholderPos;
const placeholderLength = placeholderLengthWithBrackets - 2;
const byteRange = [0, 0, 0, 0];
byteRange[1] = placeholderPos;
byteRange[2] = byteRange[1] + placeholderLengthWithBrackets;
byteRange[3] = pdf.length - byteRange[2];
let actualByteRange = `/ByteRange [${byteRange.join(' ')}]`;
actualByteRange += ' '.repeat(byteRangePlaceholder.length - actualByteRange.length); // Replace the /ByteRange placeholder with the actual ByteRange
let actualByteRange = `/ByteRange [${byteRange.join(" ")}]`;
actualByteRange += " ".repeat(byteRangePlaceholder.length - actualByteRange.length); // Replace the /ByteRange placeholder with the actual ByteRange
pdf = Buffer.concat([pdf.slice(0, byteRangePos), Buffer.from(actualByteRange), pdf.slice(byteRangeEnd)]); // Remove the placeholder signature
pdf = Buffer.concat([pdf.slice(0, byteRange[1]), pdf.slice(byteRange[2], byteRange[2] + byteRange[3])]); // Convert Buffer P12 to a forge implementation.
const forgeCert = _nodeForge.default.util.createBuffer(p12Buffer.toString('binary'));
const forgeCert = _nodeForge.default.util.createBuffer(p12Buffer.toString("binary"));
const p12Asn1 = _nodeForge.default.asn1.fromDer(forgeCert);
const p12 = _nodeForge.default.pkcs12.pkcs12FromAsn1(p12Asn1, options.asn1StrictParsing, options.passphrase); // Extract safe bags by type.
const p12 = _nodeForge.default.pkcs12.pkcs12FromAsn1(
p12Asn1,
options.asn1StrictParsing,
options.passphrase
); // Extract safe bags by type.
// We will need all the certificates and the private key.
const certBags = p12.getBags({
bagType: _nodeForge.default.pki.oids.certBag
bagType: _nodeForge.default.pki.oids.certBag,
})[_nodeForge.default.pki.oids.certBag];
const keyBags = p12.getBags({
bagType: _nodeForge.default.pki.oids.pkcs8ShroudedKeyBag
bagType: _nodeForge.default.pki.oids.pkcs8ShroudedKeyBag,
})[_nodeForge.default.pki.oids.pkcs8ShroudedKeyBag];
const privateKey = keyBags[0].key; // Here comes the actual PKCS#7 signing.
const p7 = _nodeForge.default.pkcs7.createSignedData(); // Start off by setting the content.
p7.content = _nodeForge.default.util.createBuffer(pdf.toString('binary')); // Then add all the certificates (-cacerts & -clcerts)
p7.content = _nodeForge.default.util.createBuffer(pdf.toString("binary")); // Then add all the certificates (-cacerts & -clcerts)
// Keep track of the last found client certificate.
// This will be the public key that will be bundled in the signature.
let certificate;
Object.keys(certBags).forEach(i => {
const {
publicKey
} = certBags[i].cert;
Object.keys(certBags).forEach((i) => {
const { publicKey } = certBags[i].cert;
p7.addCertificate(certBags[i].cert); // Try to find the certificate that matches the private key.
if (privateKey.n.compareTo(publicKey.n) === 0 && privateKey.e.compareTo(publicKey.e) === 0) {
@@ -137,57 +143,65 @@ class SignPdf {
}
});
if (typeof certificate === 'undefined') {
throw new _SignPdfError.default('Failed to find a certificate that matches the private key.', _SignPdfError.default.TYPE_INPUT);
if (typeof certificate === "undefined") {
throw new _SignPdfError.default(
"Failed to find a certificate that matches the private key.",
_SignPdfError.default.TYPE_INPUT
);
} // Add a sha256 signer. That's what Adobe.PPKLite adbe.pkcs7.detached expects.
p7.addSigner({
key: privateKey,
certificate,
digestAlgorithm: _nodeForge.default.pki.oids.sha256,
authenticatedAttributes: [{
type: _nodeForge.default.pki.oids.contentType,
value: _nodeForge.default.pki.oids.data
}, {
type: _nodeForge.default.pki.oids.signingTime,
// value can also be auto-populated at signing time
// We may also support passing this as an option to sign().
// Would be useful to match the creation time of the document for example.
value: new Date()
}, {
type: _nodeForge.default.pki.oids.messageDigest // value will be auto-populated at signing time
}]
authenticatedAttributes: [
{
type: _nodeForge.default.pki.oids.contentType,
value: _nodeForge.default.pki.oids.data,
},
{
type: _nodeForge.default.pki.oids.signingTime,
// value can also be auto-populated at signing time
// We may also support passing this as an option to sign().
// Would be useful to match the creation time of the document for example.
value: new Date(),
},
{
type: _nodeForge.default.pki.oids.messageDigest, // value will be auto-populated at signing time
},
],
}); // Sign in detached mode.
p7.sign({
detached: true
detached: true,
}); // Check if the PDF has a good enough placeholder to fit the signature.
const raw = _nodeForge.default.asn1.toDer(p7.toAsn1()).getBytes(); // placeholderLength represents the length of the HEXified symbols but we're
// checking the actual lengths.
if (raw.length * 2 > placeholderLength) {
throw new _SignPdfError.default(`Signature exceeds placeholder length: ${raw.length * 2} > ${placeholderLength}`, _SignPdfError.default.TYPE_INPUT);
throw new _SignPdfError.default(
`Signature exceeds placeholder length: ${raw.length * 2} > ${placeholderLength}`,
_SignPdfError.default.TYPE_INPUT
);
}
let signature = Buffer.from(raw, 'binary').toString('hex'); // Store the HEXified signature. At least useful in tests.
let signature = Buffer.from(raw, "binary").toString("hex"); // Store the HEXified signature. At least useful in tests.
this.lastSignature = signature; // Pad the signature with zeroes so the it is the same length as the placeholder
signature += Buffer.from(String.fromCharCode(0).repeat(placeholderLength / 2 - raw.length)).toString('hex'); // Place it in the document.
signature += Buffer.from(String.fromCharCode(0).repeat(placeholderLength / 2 - raw.length)).toString(
"hex"
); // Place it in the document.
pdf = Buffer.concat([pdf.slice(0, byteRange[1]), Buffer.from(`<${signature}>`), pdf.slice(byteRange[1])]); // Magic. Done.
return pdf;
}
}
exports.SignPdf = SignPdf;
var _default = new SignPdf();
exports.default = _default;
exports.default = _default;

View File

@@ -1,23 +1,15 @@
import React from "react";
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/20/solid";
import Link from "next/link";
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/20/solid";
export function Breadcrumb(props: any) {
return (
<>
<nav className="sm:hidden" aria-label="Back">
<Link
href={
props.items.length > 1
? props.items[props.items.length - 2].href
: props.items[0].href
}
className="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700"
>
<ChevronLeftIcon
className="-ml-1 mr-1 h-5 w-5 flex-shrink-0 text-gray-400"
aria-hidden="true"
/>
href={props.items.length > 1 ? props.items[props.items.length - 2].href : props.items[0].href}
className="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700">
<ChevronLeftIcon className="-ml-1 mr-1 h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
Back
</Link>
</nav>
@@ -26,19 +18,13 @@ export function Breadcrumb(props: any) {
{props?.items.map((item: any, index: number) => (
<React.Fragment key={item.href}>
{index > 0 ? (
<ChevronRightIcon
className="h-5 w-5 flex-shrink-0 text-gray-400"
aria-hidden="true"
/>
<ChevronRightIcon className="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
) : (
""
)}
<li>
<div className="flex">
<Link
href={item.href}
className="text-sm font-medium text-gray-500 hover:text-gray-700"
>
<Link href={item.href} className="text-sm font-medium text-gray-500 hover:text-gray-700">
{item.title}
</Link>
</div>

View File

@@ -1,6 +1,6 @@
import { classNames } from "@documenso/lib";
import Link from "next/link";
import React from "react";
import Link from "next/link";
import { classNames } from "@documenso/lib";
export function Button(props: any) {
const isLink = typeof props.href !== "undefined" && !props.disabled;
@@ -8,8 +8,7 @@ export function Button(props: any) {
const baseStyles =
"inline-flex items-center justify-center min-w-[80px] rounded-md border border-transparent px-4 py-2 text-sm font-medium shadow-sm disabled:bg-gray-300";
const primaryStyles = "text-white bg-neon hover:bg-neon-dark";
const secondaryStyles =
"border-gray-300 bg-white text-gray-700 hover:bg-gray-50";
const secondaryStyles = "border-gray-300 bg-white text-gray-700 hover:bg-gray-50";
return isLink ? (
<Link
@@ -20,13 +19,9 @@ export function Button(props: any) {
color === "primary" ? primaryStyles : secondaryStyles,
props.className
)}
hidden={props.hidden}
>
hidden={props.hidden}>
{props.icon ? (
<props.icon
className="inline h-5 mr-1 text-inherit"
aria-hidden="true"
></props.icon>
<props.icon className="mr-1 inline h-5 text-inherit" aria-hidden="true"></props.icon>
) : (
""
)}
@@ -43,13 +38,9 @@ export function Button(props: any) {
)}
onClick={props.onClick}
disabled={props.disabled || props.loading}
hidden={props.hidden}
>
hidden={props.hidden}>
{props.icon ? (
<props.icon
className="inline h-5 mr-1 text-inherit"
aria-hidden="true"
></props.icon>
<props.icon className="mr-1 inline h-5 text-inherit" aria-hidden="true"></props.icon>
) : (
""
)}

View File

@@ -1,6 +1,6 @@
import { classNames } from "@documenso/lib";
import Link from "next/link";
import React from "react";
import Link from "next/link";
import { classNames } from "@documenso/lib";
export function IconButton(props: any) {
const isLink = typeof props.href !== "undefined";
@@ -18,13 +18,9 @@ export function IconButton(props: any) {
color === "primary" ? primaryStyles : secondaryStyles,
props.className
)}
hidden={props.hidden}
>
hidden={props.hidden}>
{props.icon ? (
<props.icon
className="inline text-inherit h-6 mr-1"
aria-hidden="true"
></props.icon>
<props.icon className="mr-1 inline h-6 text-inherit" aria-hidden="true"></props.icon>
) : (
""
)}
@@ -40,13 +36,9 @@ export function IconButton(props: any) {
)}
onClick={props.onClick}
disabled={props.disabled}
hidden={props.hidden}
>
hidden={props.hidden}>
{props.icon ? (
<props.icon
className="inline text-inherit h-6 mr-1"
aria-hidden="true"
></props.icon>
<props.icon className="mr-1 inline h-6 text-inherit" aria-hidden="true"></props.icon>
) : (
""
)}

View File

@@ -1,8 +1,8 @@
import React from "react";
import { Transition, Dialog as DialogComponent } from "@headlessui/react";
import { Fragment } from "react";
import { Button } from "@documenso/ui";
import { sendSigningRequests } from "@documenso/lib/api";
import { Button } from "@documenso/ui";
import { Dialog as DialogComponent, Transition } from "@headlessui/react";
import { Document as PrismaDocument } from "@prisma/client";
type FormValue = {
@@ -21,18 +21,8 @@ type DialogProps = {
icon: React.ReactNode;
};
export function Dialog({
title,
open,
setOpen,
document,
formValues,
setLoading,
icon,
}: DialogProps) {
const unsentEmailsLength = formValues.filter(
(s: any) => s.email && s.sendStatus != "SENT"
).length;
export function Dialog({ title, open, setOpen, document, formValues, setLoading, icon }: DialogProps) {
const unsentEmailsLength = formValues.filter((s: any) => s.email && s.sendStatus != "SENT").length;
return (
<Transition.Root show={open} as={Fragment}>
@@ -44,13 +34,12 @@ export function Dialog({
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" />
leaveTo="opacity-0">
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex items-end justify-center min-h-full p-4 text-center sm:items-center sm:p-0">
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
@@ -58,18 +47,14 @@ export function Dialog({
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<DialogComponent.Panel className="relative px-4 pt-5 pb-4 overflow-hidden text-left transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:w-full sm:max-w-lg sm:p-6">
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<DialogComponent.Panel className="relative transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6">
<div>
<div className="flex items-center justify-center w-12 h-12 mx-auto bg-green-100 rounded-full">
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
{icon}
</div>
<div className="mt-3 text-center sm:mt-5">
<DialogComponent.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
>
<DialogComponent.Title as="h3" className="text-lg font-medium leading-6 text-gray-900">
{title}
</DialogComponent.Title>
<div className="mt-2">
@@ -79,7 +64,7 @@ export function Dialog({
</div>
</div>
</div>
<div className="flex justify-end gap-3 mt-5 sm:mt-6 sm:grid sm:grid-flow-row-dense sm:grid-cols-2 sm:flex-none ">
<div className="mt-5 flex justify-end gap-3 sm:mt-6 sm:grid sm:flex-none sm:grid-flow-row-dense sm:grid-cols-2 ">
<Button color="secondary" onClick={() => setOpen(false)}>
Cancel
</Button>
@@ -90,8 +75,7 @@ export function Dialog({
sendSigningRequests(document).finally(() => {
setLoading(false);
});
}}
>
}}>
Send
</Button>
</div>

View File

@@ -1,7 +1,7 @@
import React, { Fragment, useState } from "react";
import { classNames } from "@documenso/lib";
import { Listbox, Transition } from "@headlessui/react";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/outline";
import React, { Fragment, useState } from "react";
export function SelectBox(props: any) {
return (
@@ -10,21 +10,15 @@ export function SelectBox(props: any) {
value={props.value}
onChange={(e) => {
props.onChange(e);
}}
>
}}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700">
{props.label}
</Listbox.Label>
<Listbox.Label className="block text-sm font-medium text-gray-700">{props.label}</Listbox.Label>
<div className="relative mt-1">
<Listbox.Button className="relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left shadow-sm focus:border-neon focus:outline-none focus:ring-1 focus:ring-neon sm:text-sm">
<Listbox.Button className="focus:border-neon focus:ring-neon relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left shadow-sm focus:outline-none focus:ring-1 sm:text-sm">
<span className="block truncate">{props?.value?.label}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
<ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
@@ -33,28 +27,25 @@ export function SelectBox(props: any) {
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
leaveTo="opacity-0">
<Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{props.options.map((option: any) => (
<Listbox.Option
key={option.value}
className={({ active }) =>
classNames(
active ? "text-white bg-neon" : "text-gray-900",
active ? "bg-neon text-white" : "text-gray-900",
"relative cursor-default select-none py-2 pl-3 pr-9"
)
}
value={option}
>
value={option}>
{({ selected, active }) => (
<>
<span
className={classNames(
selected ? "font-semibold" : "font-normal",
"block truncate"
)}
>
)}>
{option.label}
</span>
@@ -63,12 +54,8 @@ export function SelectBox(props: any) {
className={classNames(
active ? "text-white" : "text-neon",
"absolute inset-y-0 right-0 flex items-center pr-4"
)}
>
<CheckIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>