Compare commits
38 Commits
v0.9
...
fix/improv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19e960f593 | ||
|
|
893ab9bea5 | ||
|
|
2aaeab3217 | ||
|
|
0a5de18235 | ||
|
|
b5e03359c1 | ||
|
|
a266e4f9d4 | ||
|
|
eccd9b5cd3 | ||
|
|
fdbcf33210 | ||
|
|
6048555e4a | ||
|
|
e33f31c483 | ||
|
|
fe82e3c84f | ||
|
|
7684a49b7d | ||
|
|
d8ad4b4b2b | ||
|
|
e40ebd84d4 | ||
|
|
a340b9c481 | ||
|
|
307b0cc9d9 | ||
|
|
3e94491474 | ||
|
|
007fe44db8 | ||
|
|
1e6f65f92d | ||
|
|
82fbedf8e3 | ||
|
|
2f3be1cfe5 | ||
|
|
8ecd5cf215 | ||
|
|
f5091dd4d7 | ||
|
|
4c06b5e640 | ||
|
|
b477799d70 | ||
|
|
b928993510 | ||
|
|
ad4d844b4d | ||
|
|
3444d7fd93 | ||
|
|
3e220135be | ||
|
|
095c391d45 | ||
|
|
b0e4fa9e1d | ||
|
|
748f842115 | ||
|
|
4a2162478e | ||
|
|
1a5948c50e | ||
|
|
8bf6594cf4 | ||
|
|
b6ff01ef86 | ||
|
|
9b993c08f1 | ||
|
|
051e681701 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -36,3 +36,6 @@ yarn-error.log*
|
|||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
.env
|
.env
|
||||||
.env.example
|
.env.example
|
||||||
|
|
||||||
|
# turborepo
|
||||||
|
.turbo
|
||||||
20
README.md
20
README.md
@@ -1,7 +1,11 @@
|
|||||||
> <strong>We are launching TOMORROW on Product Hunt soon! Sign up to support the launch: </strong>
|
<div align="center" style="margin-top: 12px; margin-bottom: 3332px;">
|
||||||
> <center><a href="https://dub.sh/documenso-launch"><img src="https://img.shields.io/badge/Documenso%20on%20Product%20Hunt-Notify%20Me-orange" alt="Product Hunt"></a></center>
|
<p>
|
||||||
|
We are LIVE on Product Hunt. Come say hi..
|
||||||
<p align="center" style="margin-top: 12px">
|
</p>
|
||||||
|
<a href="https://www.producthunt.com/posts/documenso?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-documenso" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=395047&theme=light" alt="Documenso - The Open Source DocuSign Alternative. | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<p align="center" style="margin-top: 120px">
|
||||||
<a href="https://github.com/documenso/documenso.com">
|
<a href="https://github.com/documenso/documenso.com">
|
||||||
<img width="250px" src="https://github.com/documenso/documenso/assets/1309312/cd7823ec-4baa-40b9-be78-4acb3b1c73cb" alt="Documenso Logo">
|
<img width="250px" src="https://github.com/documenso/documenso/assets/1309312/cd7823ec-4baa-40b9-be78-4acb3b1c73cb" alt="Documenso Logo">
|
||||||
</a>
|
</a>
|
||||||
@@ -74,8 +78,6 @@ The current project goal is to <b>[release a production ready version](https://g
|
|||||||
|
|
||||||
- To contribute please see our [contribution guide](https://github.com/documenso/documenso/blob/main/CONTRIBUTING.md).
|
- To contribute please see our [contribution guide](https://github.com/documenso/documenso/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Tech
|
# Tech
|
||||||
|
|
||||||
Documenso is built using awesome open source tech including:
|
Documenso is built using awesome open source tech including:
|
||||||
@@ -153,10 +155,10 @@ Follow these steps to setup documenso on you local machine:
|
|||||||
---
|
---
|
||||||
|
|
||||||
- Optional: Seed the database using <code>npm run db-seed</code> to create a test user and document
|
- Optional: Seed the database using <code>npm run db-seed</code> to create a test user and document
|
||||||
- Optional: Upload and sign <code>apps/web/ressources/example.pdf</code> manually to test your setup
|
- Optional: Upload and sign <code>apps/web/resources/example.pdf</code> manually to test your setup
|
||||||
|
|
||||||
- Optional: Create your own signing certificate
|
- Optional: Create your own signing certificate
|
||||||
- A demo certificate is provided in `/app/web/ressources/certificate.p12`
|
- A demo certificate is provided in `/app/web/resources/certificate.p12`
|
||||||
- To generate your own using these steps and a Linux Terminal or Windows Subsystem for Linux (WSL) see **[Create your own signing certificate](#creating-your-own-signing-certificate)**.
|
- To generate your own using these steps and a Linux Terminal or Windows Subsystem for Linux (WSL) see **[Create your own signing certificate](#creating-your-own-signing-certificate)**.
|
||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
@@ -181,7 +183,7 @@ For the digital signature of your documents you need a signing certificate in .p
|
|||||||
3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following command to do this: \
|
3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following command to do this: \
|
||||||
<code>openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt</code>
|
<code>openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt</code>
|
||||||
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
|
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
|
||||||
5. Place the certificate <code>/apps/web/ressource/certificate.p12</code>
|
5. Place the certificate <code>/apps/web/resources/certificate.p12</code>
|
||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import Link from "next/link";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from "@documenso/lib/constants";
|
import { NEXT_PUBLIC_WEBAPP_URL } from "@documenso/lib/constants";
|
||||||
import { useSubscription } from "@documenso/lib/stripe";
|
import { useSubscription } from "@documenso/lib/stripe";
|
||||||
|
import { BillingWarning } from "./billing-warning";
|
||||||
import Navigation from "./navigation";
|
import Navigation from "./navigation";
|
||||||
import { PaperAirplaneIcon } from "@heroicons/react/24/outline";
|
import { PaperAirplaneIcon } from "@heroicons/react/24/outline";
|
||||||
import { SubscriptionStatus } from "@prisma/client";
|
import { SubscriptionStatus } from "@prisma/client";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { BillingWarning } from "./billing-warning";
|
|
||||||
|
|
||||||
function useRedirectToLoginIfUnauthenticated() {
|
function useRedirectToLoginIfUnauthenticated() {
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ export default function TopNavigation() {
|
|||||||
href="/dashboard"
|
href="/dashboard"
|
||||||
className="flex flex-shrink-0 items-center gap-x-2 self-center overflow-hidden">
|
className="flex flex-shrink-0 items-center gap-x-2 self-center overflow-hidden">
|
||||||
<Logo className="h-8 w-8" />
|
<Logo className="h-8 w-8" />
|
||||||
<h2 className="text-2xl font-semibold">Documenso</h2>
|
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
|
<div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ require("dotenv").config({ path: "../../.env" });
|
|||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
swcMinify: false,
|
swcMinify: false,
|
||||||
};
|
transpilePackages: [
|
||||||
|
|
||||||
const transpileModules = require("next-transpile-modules")([
|
|
||||||
"@documenso/prisma",
|
"@documenso/prisma",
|
||||||
"@documenso/lib",
|
"@documenso/lib",
|
||||||
"@documenso/ui",
|
"@documenso/ui",
|
||||||
@@ -14,12 +12,7 @@ const transpileModules = require("next-transpile-modules")([
|
|||||||
"@documenso/features",
|
"@documenso/features",
|
||||||
"@documenso/signing",
|
"@documenso/signing",
|
||||||
"react-signature-canvas",
|
"react-signature-canvas",
|
||||||
]);
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const plugins = [
|
module.exports = nextConfig;
|
||||||
transpileModules
|
|
||||||
];
|
|
||||||
|
|
||||||
const moduleExports = () => plugins.reduce((acc, next) => next(acc), nextConfig);
|
|
||||||
|
|
||||||
module.exports = moduleExports;
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"eslint-config-next": "13.0.3",
|
"eslint-config-next": "13.0.3",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"next-transpile-modules": "^10.0.0",
|
|
||||||
"postcss": "^8.4.19",
|
"postcss": "^8.4.19",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.57.1",
|
||||||
"stripe-cli": "^0.1.0",
|
"stripe-cli": "^0.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ReactElement, ReactNode } from "react";
|
import { ReactElement, ReactNode } from "react";
|
||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
import type { AppProps } from "next/app";
|
import type { AppProps } from "next/app";
|
||||||
|
import { Montserrat, Qwigley } from "next/font/google";
|
||||||
import { SubscriptionProvider } from "@documenso/lib/stripe/providers/subscription-provider";
|
import { SubscriptionProvider } from "@documenso/lib/stripe/providers/subscription-provider";
|
||||||
import "../../../node_modules/placeholder-loading/src/scss/placeholder-loading.scss";
|
import "../../../node_modules/placeholder-loading/src/scss/placeholder-loading.scss";
|
||||||
import "../../../node_modules/react-resizable/css/styles.css";
|
import "../../../node_modules/react-resizable/css/styles.css";
|
||||||
@@ -11,6 +12,20 @@ import "react-tooltip/dist/react-tooltip.css";
|
|||||||
|
|
||||||
export { coloredConsole } from "@documenso/lib";
|
export { coloredConsole } from "@documenso/lib";
|
||||||
|
|
||||||
|
const montserrat = Montserrat({
|
||||||
|
subsets: ["latin"],
|
||||||
|
weight: ["400", "700"],
|
||||||
|
display: "swap",
|
||||||
|
variable: "--font-sans",
|
||||||
|
});
|
||||||
|
|
||||||
|
const qwigley = Qwigley({
|
||||||
|
subsets: ["latin"],
|
||||||
|
weight: ["400"],
|
||||||
|
display: "swap",
|
||||||
|
variable: "--font-qwigley",
|
||||||
|
});
|
||||||
|
|
||||||
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
||||||
getLayout?: (page: ReactElement) => ReactNode;
|
getLayout?: (page: ReactElement) => ReactNode;
|
||||||
};
|
};
|
||||||
@@ -27,8 +42,10 @@ export default function App({
|
|||||||
return (
|
return (
|
||||||
<SessionProvider session={session}>
|
<SessionProvider session={session}>
|
||||||
<SubscriptionProvider initialSubscription={initialSubscription}>
|
<SubscriptionProvider initialSubscription={initialSubscription}>
|
||||||
|
<main className={`${montserrat.variable} h-full font-sans`}>
|
||||||
<Toaster position="top-center" />
|
<Toaster position="top-center" />
|
||||||
{getLayout(<Component {...pageProps} />)}
|
{getLayout(<Component {...pageProps} />)}
|
||||||
|
</main>
|
||||||
</SubscriptionProvider>
|
</SubscriptionProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import prisma from "@documenso/prisma";
|
|||||||
import { Button, IconButton } from "@documenso/ui";
|
import { Button, IconButton } from "@documenso/ui";
|
||||||
import { NextPageWithLayout } from "../../_app";
|
import { NextPageWithLayout } from "../../_app";
|
||||||
import { ArrowDownTrayIcon, CheckBadgeIcon } from "@heroicons/react/24/outline";
|
import { ArrowDownTrayIcon, CheckBadgeIcon } from "@heroicons/react/24/outline";
|
||||||
|
import { truncate } from "@documenso/lib/helpers";
|
||||||
|
|
||||||
const Signed: NextPageWithLayout = (props: any) => {
|
const Signed: NextPageWithLayout = (props: any) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -21,7 +22,7 @@ const Signed: NextPageWithLayout = (props: any) => {
|
|||||||
<CheckBadgeIcon className="text-neon mr-1 inline w-10"></CheckBadgeIcon>
|
<CheckBadgeIcon className="text-neon mr-1 inline w-10"></CheckBadgeIcon>
|
||||||
<h1 className="text-neon inline align-middle text-base font-medium">It's done!</h1>
|
<h1 className="text-neon inline align-middle text-base font-medium">It's done!</h1>
|
||||||
<p className="mt-2 text-4xl font-bold tracking-tight">
|
<p className="mt-2 text-4xl font-bold tracking-tight">
|
||||||
You signed "{props.document.title}"
|
You signed "{truncate(props.document.title)}"
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2 max-w-sm text-base text-gray-500" hidden={allRecipientsSigned}>
|
<p className="mt-2 max-w-sm text-base text-gray-500" hidden={allRecipientsSigned}>
|
||||||
You will be notfied when all recipients have signed.
|
You will be notfied when all recipients have signed.
|
||||||
|
|||||||
@@ -6,35 +6,3 @@
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
|
||||||
body,
|
|
||||||
:host {
|
|
||||||
font-family: montserrat;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Qwigley";
|
|
||||||
src: url("/fonts/Qwigley-Regular.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: "Montserrat";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
font-display: swap;
|
|
||||||
src: url("/fonts/montserrat.woff2") format("woff2");
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F,
|
|
||||||
U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: "Montserrat";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
font-display: swap;
|
|
||||||
src: url("/fonts/montserrat.woff2") format("woff2");
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F,
|
|
||||||
U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ module.exports = {
|
|||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
monteserrat: ["Monteserrat", "serif"],
|
sans: ["var(--font-sans)", ...defaultTheme.fontFamily.sans],
|
||||||
qwigley: ["Qwigley", "serif"],
|
qwigley: ["var(--font-qwigley)", "serif"],
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
neon: {
|
neon: {
|
||||||
@@ -58,6 +58,19 @@ module.exports = {
|
|||||||
900: "#000000",
|
900: "#000000",
|
||||||
950: "#000000",
|
950: "#000000",
|
||||||
},
|
},
|
||||||
|
brand: {
|
||||||
|
DEFAULT: "#A2E771",
|
||||||
|
100: "#F4FCEE",
|
||||||
|
200: "#E8F9DC",
|
||||||
|
300: "#D1F3B9",
|
||||||
|
400: "#BBED96",
|
||||||
|
500: "#A2E771",
|
||||||
|
600: "#8DE151",
|
||||||
|
700: "#76DC2E",
|
||||||
|
800: "#63C021",
|
||||||
|
900: "#519D1B",
|
||||||
|
950: "#488C18",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
"4xl": "2rem",
|
"4xl": "2rem",
|
||||||
|
|||||||
309
package-lock.json
generated
309
package-lock.json
generated
@@ -40,6 +40,7 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"prettier-plugin-tailwindcss": "^0.2.5",
|
"prettier-plugin-tailwindcss": "^0.2.5",
|
||||||
|
"turbo": "^1.9.9",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -92,7 +93,6 @@
|
|||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"eslint-config-next": "13.0.3",
|
"eslint-config-next": "13.0.3",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"next-transpile-modules": "^10.0.0",
|
|
||||||
"postcss": "^8.4.19",
|
"postcss": "^8.4.19",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.57.1",
|
||||||
"stripe-cli": "^0.1.0",
|
"stripe-cli": "^0.1.0",
|
||||||
@@ -633,36 +633,6 @@
|
|||||||
"glob": "7.1.7"
|
"glob": "7.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-android-arm-eabi": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-DWlalTSkLjDU11MY11jg17O1gGQzpRccM9Oes2yTqj2DpHndajrXHGxj9HGtJ+idq2k7ImUdJVWS2h2l/EDJOw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-android-arm64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-sRavmUImUCf332Gy+PjIfLkMhiRX1Ez4SI+3vFDRs1N5eXp+uNzjFUK/oLMMOzk6KFSkbiK/3Wt8+dHQR/flNg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
"version": "13.2.4",
|
"version": "13.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.4.tgz",
|
||||||
@@ -678,156 +648,6 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-a6LBuoYGcFOPGd4o8TPo7wmv5FnMr+Prz+vYHopEDuhDoMSHOnC+v+Ab4D7F0NMZkvQjEJQdJS3rqgFhlZmKlw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-freebsd-x64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-kkbzKVZGPaXRBPisoAQkh3xh22r+TD+5HwoC5bOkALraJ0dsOQgSMAvzMXKsN3tMzJUPS0tjtRf1cTzrQ0I5vQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"freebsd"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-arm-gnueabihf": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-7qA1++UY0fjprqtjBZaOA6cas/7GekpjVsZn/0uHvquuITFCdKGFCsKNBx3S0Rpxmx6WYo0GcmhNRM9ru08BGg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-xzYZdAeq883MwXgcwc72hqo/F/dwUxCukpDOkx/j1HTq/J0wJthMGjinN9wH5bPR98Mfeh1MZJ91WWPnZOedOg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-8rXr3WfmqSiYkb71qzuDP6I6R2T2tpkmf83elDN8z783N9nvTJf2E7eLx86wu2OJCi4T05nuxCsh4IOU3LQ5xw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-Ngxh51zGSlYJ4EfpKG4LI6WfquulNdtmHg1yuOYlaAr33KyPJp4HeN/tivBnAHcZkoNy0hh/SbwDyCnz5PFJQQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-gOvwIYoSxd+j14LOcvJr+ekd9fwYT1RyMAHOp7znA10+l40wkFiMONPLWiZuHxfRk+Dy7YdNdDh3ImumvL6VwA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-q3NJzcfClgBm4HvdcnoEncmztxrA5GXqKeiZ/hADvC56pwNALt3ngDC6t6qr1YW9V/EPDxCYeaX4zYxHciW4Dw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-/eZ5ncmHUYtD2fc6EUmAIZlAJnVT2YmxDsKs1Ourx0ttTtvtma/WKlMV5NoUsyOez0f9ExLyOpeCoz5aj+MPXw==",
|
|
||||||
"cpu": [
|
|
||||||
"ia32"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-0MffFmyv7tBLlji01qc0IaPP/LVExzvj7/R5x1Jph1bTAIj4Vu81yFQWHHQAP6r4ff9Ukj1mBK6MDNVXm7Tcvw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -3652,7 +3472,6 @@
|
|||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -7665,6 +7484,37 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/turbo": {
|
||||||
|
"version": "1.9.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbo/-/turbo-1.9.9.tgz",
|
||||||
|
"integrity": "sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"turbo": "bin/turbo"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"turbo-darwin-64": "1.9.9",
|
||||||
|
"turbo-darwin-arm64": "1.9.9",
|
||||||
|
"turbo-linux-64": "1.9.9",
|
||||||
|
"turbo-linux-arm64": "1.9.9",
|
||||||
|
"turbo-windows-64": "1.9.9",
|
||||||
|
"turbo-windows-arm64": "1.9.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/turbo-darwin-arm64": {
|
||||||
|
"version": "1.9.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.9.9.tgz",
|
||||||
|
"integrity": "sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/tweetnacl": {
|
"node_modules/tweetnacl": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
@@ -8517,7 +8367,6 @@
|
|||||||
"formidable": "^3.2.5",
|
"formidable": "^3.2.5",
|
||||||
"next": "13.2.4",
|
"next": "13.2.4",
|
||||||
"next-auth": "^4.22.0",
|
"next-auth": "^4.22.0",
|
||||||
"next-transpile-modules": "^10.0.0",
|
|
||||||
"node-forge": "^1.3.1",
|
"node-forge": "^1.3.1",
|
||||||
"node-signpdf": "^1.5.0",
|
"node-signpdf": "^1.5.0",
|
||||||
"nodemailer": "^6.9.0",
|
"nodemailer": "^6.9.0",
|
||||||
@@ -8681,84 +8530,12 @@
|
|||||||
"glob": "7.1.7"
|
"glob": "7.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@next/swc-android-arm-eabi": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-DWlalTSkLjDU11MY11jg17O1gGQzpRccM9Oes2yTqj2DpHndajrXHGxj9HGtJ+idq2k7ImUdJVWS2h2l/EDJOw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-android-arm64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-sRavmUImUCf332Gy+PjIfLkMhiRX1Ez4SI+3vFDRs1N5eXp+uNzjFUK/oLMMOzk6KFSkbiK/3Wt8+dHQR/flNg==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-darwin-arm64": {
|
"@next/swc-darwin-arm64": {
|
||||||
"version": "13.2.4",
|
"version": "13.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.4.tgz",
|
||||||
"integrity": "sha512-S6vBl+OrInP47TM3LlYx65betocKUUlTZDDKzTiRDbsRESeyIkBtZ6Qi5uT2zQs4imqllJznVjFd1bXLx3Aa6A==",
|
"integrity": "sha512-S6vBl+OrInP47TM3LlYx65betocKUUlTZDDKzTiRDbsRESeyIkBtZ6Qi5uT2zQs4imqllJznVjFd1bXLx3Aa6A==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@next/swc-darwin-x64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-a6LBuoYGcFOPGd4o8TPo7wmv5FnMr+Prz+vYHopEDuhDoMSHOnC+v+Ab4D7F0NMZkvQjEJQdJS3rqgFhlZmKlw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-freebsd-x64": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-kkbzKVZGPaXRBPisoAQkh3xh22r+TD+5HwoC5bOkALraJ0dsOQgSMAvzMXKsN3tMzJUPS0tjtRf1cTzrQ0I5vQ==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-linux-arm-gnueabihf": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-7qA1++UY0fjprqtjBZaOA6cas/7GekpjVsZn/0uHvquuITFCdKGFCsKNBx3S0Rpxmx6WYo0GcmhNRM9ru08BGg==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-linux-arm64-gnu": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-xzYZdAeq883MwXgcwc72hqo/F/dwUxCukpDOkx/j1HTq/J0wJthMGjinN9wH5bPR98Mfeh1MZJ91WWPnZOedOg==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-linux-arm64-musl": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-8rXr3WfmqSiYkb71qzuDP6I6R2T2tpkmf83elDN8z783N9nvTJf2E7eLx86wu2OJCi4T05nuxCsh4IOU3LQ5xw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-linux-x64-gnu": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-Ngxh51zGSlYJ4EfpKG4LI6WfquulNdtmHg1yuOYlaAr33KyPJp4HeN/tivBnAHcZkoNy0hh/SbwDyCnz5PFJQQ==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-linux-x64-musl": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-gOvwIYoSxd+j14LOcvJr+ekd9fwYT1RyMAHOp7znA10+l40wkFiMONPLWiZuHxfRk+Dy7YdNdDh3ImumvL6VwA==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-win32-arm64-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-q3NJzcfClgBm4HvdcnoEncmztxrA5GXqKeiZ/hADvC56pwNALt3ngDC6t6qr1YW9V/EPDxCYeaX4zYxHciW4Dw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-win32-ia32-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-/eZ5ncmHUYtD2fc6EUmAIZlAJnVT2YmxDsKs1Ourx0ttTtvtma/WKlMV5NoUsyOez0f9ExLyOpeCoz5aj+MPXw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@next/swc-win32-x64-msvc": {
|
|
||||||
"version": "13.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.4.tgz",
|
|
||||||
"integrity": "sha512-0MffFmyv7tBLlji01qc0IaPP/LVExzvj7/R5x1Jph1bTAIj4Vu81yFQWHHQAP6r4ff9Ukj1mBK6MDNVXm7Tcvw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -11012,7 +10789,6 @@
|
|||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
@@ -13859,6 +13635,27 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"turbo": {
|
||||||
|
"version": "1.9.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbo/-/turbo-1.9.9.tgz",
|
||||||
|
"integrity": "sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"turbo-darwin-64": "1.9.9",
|
||||||
|
"turbo-darwin-arm64": "1.9.9",
|
||||||
|
"turbo-linux-64": "1.9.9",
|
||||||
|
"turbo-linux-arm64": "1.9.9",
|
||||||
|
"turbo-windows-64": "1.9.9",
|
||||||
|
"turbo-windows-arm64": "1.9.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turbo-darwin-arm64": {
|
||||||
|
"version": "1.9.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.9.9.tgz",
|
||||||
|
"integrity": "sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"tweetnacl": {
|
"tweetnacl": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
"name": "documenso-monorepo",
|
"name": "documenso-monorepo",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "npm run dev -w apps/web",
|
"dev": "turbo run dev --filter=web",
|
||||||
"build": "npm i && cd apps && cd web && npm i && next build",
|
"build": "turbo run build --filter=web",
|
||||||
"start": "cd apps && cd web && next start",
|
"start": "turbo run start --filter=web",
|
||||||
"db-migrate:dev": "prisma migrate dev",
|
"db-migrate:dev": "prisma migrate dev",
|
||||||
"db-seed": "prisma db seed",
|
"db-seed": "prisma db seed",
|
||||||
"db-studio": "prisma studio",
|
"db-studio": "prisma studio",
|
||||||
"docker:compose": "docker-compose -f ./docker/compose-without-app.yml",
|
"docker:compose": "docker compose -f ./docker/compose-without-app.yml || docker-compose -f ./docker/compose-without-app.yml",
|
||||||
"docker:compose-up": "npm run docker:compose -- up -d",
|
"docker:compose-up": "npm run docker:compose -- up -d",
|
||||||
"docker:compose-down": "npm run docker:compose -- down",
|
"docker:compose-down": "npm run docker:compose -- down",
|
||||||
"stripe:listen": "stripe listen --forward-to localhost:3000/api/stripe/webhook",
|
"stripe:listen": "stripe listen --forward-to localhost:3000/api/stripe/webhook",
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"prettier-plugin-tailwindcss": "^0.2.5",
|
"prettier-plugin-tailwindcss": "^0.2.5",
|
||||||
|
"turbo": "^1.9.9",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
packages/lib/helpers/index.ts
Normal file
1
packages/lib/helpers/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './strings';
|
||||||
13
packages/lib/helpers/strings.ts
Normal file
13
packages/lib/helpers/strings.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Truncates a title to a given max length substituting the middle with an ellipsis.
|
||||||
|
*/
|
||||||
|
export const truncate = (str: string, maxLength: number = 20) => {
|
||||||
|
if (str.length <= maxLength) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startLength = Math.ceil((maxLength - 3) / 2);
|
||||||
|
const endLength = Math.floor((maxLength - 3) / 2);
|
||||||
|
|
||||||
|
return `${str.slice(0, startLength)}...${str.slice(-endLength)}`;
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { HttpError } from "@documenso/lib/server";
|
import { HttpError } from "@documenso/lib/server";
|
||||||
import { NotFoundError, PrismaClientKnownRequestError } from "@prisma/client/runtime";
|
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
||||||
|
|
||||||
export function getServerErrorFromUnknown(cause: unknown): HttpError {
|
export function getServerErrorFromUnknown(cause: unknown): HttpError {
|
||||||
// Error was manually thrown and does not need to be parsed.
|
// Error was manually thrown and does not need to be parsed.
|
||||||
@@ -18,7 +18,7 @@ export function getServerErrorFromUnknown(cause: unknown): HttpError {
|
|||||||
return new HttpError({ statusCode: 400, message: cause.message, cause });
|
return new HttpError({ statusCode: 400, message: cause.message, cause });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause instanceof NotFoundError) {
|
if (cause instanceof PrismaClientKnownRequestError) {
|
||||||
return new HttpError({ statusCode: 404, message: cause.message, cause });
|
return new HttpError({ statusCode: 404, message: cause.message, cause });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
log("constructing body...")
|
|
||||||
const body = await buffer(req);
|
const body = await buffer(req);
|
||||||
log("constructed body")
|
|
||||||
|
|
||||||
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
|
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
|
||||||
log("event-type:", event.type);
|
log("event-type:", event.type);
|
||||||
@@ -70,11 +68,25 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
if (event.type === "invoice.payment_succeeded") {
|
if (event.type === "invoice.payment_succeeded") {
|
||||||
const invoice = event.data.object as Stripe.Invoice;
|
const invoice = event.data.object as Stripe.Invoice;
|
||||||
|
|
||||||
|
if (invoice.billing_reason !== "subscription_cycle") {
|
||||||
|
return res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
message: "Webhook received",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const customerId =
|
const customerId =
|
||||||
typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id;
|
typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id;
|
||||||
|
|
||||||
const subscription = await stripe.subscriptions.retrieve(invoice.subscription as string);
|
const subscription = await stripe.subscriptions.retrieve(invoice.subscription as string);
|
||||||
|
|
||||||
|
const hasSubscription = await prisma.subscription.findFirst({
|
||||||
|
where: {
|
||||||
|
customerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasSubscription) {
|
||||||
await prisma.subscription.update({
|
await prisma.subscription.update({
|
||||||
where: {
|
where: {
|
||||||
customerId,
|
customerId,
|
||||||
@@ -86,6 +98,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
periodEnd: new Date(subscription.current_period_end * 1000),
|
periodEnd: new Date(subscription.current_period_end * 1000),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -98,6 +111,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
const customerId = failedInvoice.customer as string;
|
const customerId = failedInvoice.customer as string;
|
||||||
|
|
||||||
|
const hasSubscription = await prisma.subscription.findFirst({
|
||||||
|
where: {
|
||||||
|
customerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasSubscription) {
|
||||||
await prisma.subscription.update({
|
await prisma.subscription.update({
|
||||||
where: {
|
where: {
|
||||||
customerId,
|
customerId,
|
||||||
@@ -106,6 +126,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
status: SubscriptionStatus.PAST_DUE,
|
status: SubscriptionStatus.PAST_DUE,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -118,6 +139,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
const customerId = updatedSubscription.customer as string;
|
const customerId = updatedSubscription.customer as string;
|
||||||
|
|
||||||
|
const hasSubscription = await prisma.subscription.findFirst({
|
||||||
|
where: {
|
||||||
|
customerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasSubscription) {
|
||||||
await prisma.subscription.update({
|
await prisma.subscription.update({
|
||||||
where: {
|
where: {
|
||||||
customerId,
|
customerId,
|
||||||
@@ -129,6 +157,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
periodEnd: new Date(updatedSubscription.current_period_end * 1000),
|
periodEnd: new Date(updatedSubscription.current_period_end * 1000),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -141,6 +170,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
const customerId = deletedSubscription.customer as string;
|
const customerId = deletedSubscription.customer as string;
|
||||||
|
|
||||||
|
const hasSubscription = await prisma.subscription.findFirst({
|
||||||
|
where: {
|
||||||
|
customerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasSubscription) {
|
||||||
await prisma.subscription.update({
|
await prisma.subscription.update({
|
||||||
where: {
|
where: {
|
||||||
customerId,
|
customerId,
|
||||||
@@ -149,6 +185,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
|
|||||||
status: SubscriptionStatus.INACTIVE,
|
status: SubscriptionStatus.INACTIVE,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const addDigitalSignature = async (documentAsBase64: string): Promise<str
|
|||||||
const pdfBuffer = Buffer.from(documentAsBase64, "base64");
|
const pdfBuffer = Buffer.from(documentAsBase64, "base64");
|
||||||
const p12Buffer = Buffer.from(
|
const p12Buffer = Buffer.from(
|
||||||
fs
|
fs
|
||||||
.readFileSync(process.env.CERT_FILE_PATH || "ressources/certificate.p12")
|
.readFileSync(process.env.CERT_FILE_PATH || "resources/certificate.p12")
|
||||||
.toString(process.env.CERT_FILE_ENCODING ? undefined : "binary"),
|
.toString(process.env.CERT_FILE_ENCODING ? undefined : "binary"),
|
||||||
(process.env.CERT_FILE_ENCODING as BufferEncoding) || "binary"
|
(process.env.CERT_FILE_ENCODING as BufferEncoding) || "binary"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React, { useMemo } from "react";
|
||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
import { sendSigningRequests } from "@documenso/lib/api";
|
import { sendSigningRequests } from "@documenso/lib/api";
|
||||||
|
import { truncate } from "@documenso/lib/helpers";
|
||||||
import { Button } from "@documenso/ui";
|
import { Button } from "@documenso/ui";
|
||||||
import { Dialog as DialogComponent, Transition } from "@headlessui/react";
|
import { Dialog as DialogComponent, Transition } from "@headlessui/react";
|
||||||
import { Document as PrismaDocument } from "@prisma/client";
|
import { Document as PrismaDocument } from "@prisma/client";
|
||||||
@@ -19,6 +20,7 @@ type DialogProps = {
|
|||||||
formValues: FormValue[];
|
formValues: FormValue[];
|
||||||
setLoading: (loading: boolean) => void;
|
setLoading: (loading: boolean) => void;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
truncateTitle?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Dialog({
|
export function Dialog({
|
||||||
@@ -29,11 +31,14 @@ export function Dialog({
|
|||||||
formValues,
|
formValues,
|
||||||
setLoading,
|
setLoading,
|
||||||
icon,
|
icon,
|
||||||
|
truncateTitle = true,
|
||||||
}: DialogProps) {
|
}: DialogProps) {
|
||||||
const unsentEmailsLength = formValues.filter(
|
const unsentEmailsLength = formValues.filter(
|
||||||
(s: any) => s.email && s.sendStatus != "SENT"
|
(s: any) => s.email && s.sendStatus != "SENT"
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
|
const documentTitle = truncateTitle ? truncate(document.title) : document.title;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition.Root show={open} as={Fragment}>
|
<Transition.Root show={open} as={Fragment}>
|
||||||
<DialogComponent as="div" className="relative z-10" onClose={setOpen}>
|
<DialogComponent as="div" className="relative z-10" onClose={setOpen}>
|
||||||
@@ -71,7 +76,7 @@ export function Dialog({
|
|||||||
</DialogComponent.Title>
|
</DialogComponent.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
{`"${document.title}" will be sent to ${unsentEmailsLength} recipients.`}
|
{`"${documentTitle}" will be sent to ${unsentEmailsLength} recipients.`}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
38
turbo.json
Normal file
38
turbo.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://turbo.build/schema.json",
|
||||||
|
"globalEnv": [
|
||||||
|
"DATABASE_URL",
|
||||||
|
"NEXT_PUBLIC_WEBAPP_URL",
|
||||||
|
"NEXTAUTH_SECRET",
|
||||||
|
"NEXTAUTH_URL",
|
||||||
|
"CERT_FILE_PATH",
|
||||||
|
"CERT_PASSPHRASE",
|
||||||
|
"CERT_FILE_ENCODING",
|
||||||
|
"SENDGRID_API_KEY",
|
||||||
|
"SMTP_MAIL_HOST",
|
||||||
|
"SMTP_MAIL_PORT",
|
||||||
|
"SMTP_MAIL_USER",
|
||||||
|
"SMTP_MAIL_PASSWORD",
|
||||||
|
"MAIL_FROM",
|
||||||
|
"STRIPE_API_KEY",
|
||||||
|
"STRIPE_WEBHOOK_SECRET",
|
||||||
|
"NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID",
|
||||||
|
"NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_YEARLY_PRICE_ID",
|
||||||
|
"NEXT_PUBLIC_ALLOW_SIGNUP",
|
||||||
|
"NEXT_PUBLIC_ALLOW_SUBSCRIPTIONS"
|
||||||
|
],
|
||||||
|
"pipeline": {
|
||||||
|
"build": {
|
||||||
|
"outputs": [".next/**", "!.next/cache/**"]
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"dependsOn": ["build"],
|
||||||
|
"cache": false,
|
||||||
|
"persistent": true
|
||||||
|
},
|
||||||
|
"dev": {
|
||||||
|
"cache": false,
|
||||||
|
"persistent": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user