Merge branch 'main' into feat/webhook-implementation

This commit is contained in:
Lucas Smith
2024-02-26 12:47:21 +11:00
committed by GitHub
196 changed files with 10026 additions and 1102 deletions

View File

@ -0,0 +1,21 @@
-- CreateEnum
CREATE TYPE "ApiTokenAlgorithm" AS ENUM ('SHA512');
-- CreateTable
CREATE TABLE "ApiToken" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"token" TEXT NOT NULL,
"algorithm" "ApiTokenAlgorithm" NOT NULL DEFAULT 'SHA512',
"expires" TIMESTAMP(3) NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" INTEGER NOT NULL,
CONSTRAINT "ApiToken_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "ApiToken_token_key" ON "ApiToken"("token");
-- AddForeignKey
ALTER TABLE "ApiToken" ADD CONSTRAINT "ApiToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "ApiToken" DROP CONSTRAINT "ApiToken_userId_fkey";
-- AddForeignKey
ALTER TABLE "ApiToken" ADD CONSTRAINT "ApiToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,30 @@
-- Create deleted@documenso.com
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM "public"."User" WHERE "email" = 'deleted-account@documenso.com') THEN
INSERT INTO
"public"."User" (
"email",
"emailVerified",
"password",
"createdAt",
"updatedAt",
"lastSignedIn",
"roles",
"identityProvider",
"twoFactorEnabled"
)
VALUES
(
'deleted-account@documenso.com',
NOW(),
NULL,
NOW(),
NOW(),
NOW(),
ARRAY['USER'::TEXT]::"public"."Role" [],
CAST('GOOGLE'::TEXT AS "public"."IdentityProvider"),
FALSE
);
END IF;
END $$

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "ApiToken" ALTER COLUMN "expires" DROP NOT NULL;

View File

@ -0,0 +1,6 @@
-- AlterTable
ALTER TABLE "ApiToken" ADD COLUMN "teamId" INTEGER,
ALTER COLUMN "userId" DROP NOT NULL;
-- AddForeignKey
ALTER TABLE "ApiToken" ADD CONSTRAINT "ApiToken_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,12 @@
-- CreateTable
CREATE TABLE "Banner" (
"id" SERIAL NOT NULL,
"text" TEXT NOT NULL,
"customHTML" TEXT NOT NULL,
"userId" INTEGER,
CONSTRAINT "Banner_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Banner" ADD CONSTRAINT "Banner_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Banner" ADD COLUMN "show" BOOLEAN NOT NULL DEFAULT false;

View File

@ -0,0 +1,8 @@
/*
Warnings:
- You are about to drop the column `customHTML` on the `Banner` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Banner" DROP COLUMN "customHTML";

View File

@ -0,0 +1,25 @@
/*
Warnings:
- You are about to drop the `Banner` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "Banner" DROP CONSTRAINT "Banner_userId_fkey";
-- DropTable
DROP TABLE "Banner";
-- CreateTable
CREATE TABLE "SiteSettings" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"data" JSONB NOT NULL,
"lastModifiedByUserId" INTEGER,
"lastModifiedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SiteSettings_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "SiteSettings" ADD CONSTRAINT "SiteSettings_lastModifiedByUserId_fkey" FOREIGN KEY ("lastModifiedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,13 @@
INSERT INTO "SiteSettings" ("id", "enabled", "data")
VALUES (
'site.banner',
FALSE,
jsonb_build_object(
'content',
'This is a test banner',
'bgColor',
'#000000',
'textColor',
'#ffffff'
)
);

View File

@ -19,19 +19,19 @@ enum Role {
}
model User {
id Int @id @default(autoincrement())
id Int @id @default(autoincrement())
name String?
customerId String? @unique
email String @unique
customerId String? @unique
email String @unique
emailVerified DateTime?
password String?
source String?
signature String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
lastSignedIn DateTime @default(now())
roles Role[] @default([USER])
identityProvider IdentityProvider @default(DOCUMENSO)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
lastSignedIn DateTime @default(now())
roles Role[] @default([USER])
identityProvider IdentityProvider @default(DOCUMENSO)
accounts Account[]
sessions Session[]
Document Document[]
@ -41,13 +41,15 @@ model User {
ownedPendingTeams TeamPending[]
teamMembers TeamMember[]
twoFactorSecret String?
twoFactorEnabled Boolean @default(false)
twoFactorEnabled Boolean @default(false)
twoFactorBackupCodes String?
VerificationToken VerificationToken[]
ApiToken ApiToken[]
Template Template[]
securityAuditLogs UserSecurityAuditLog[]
Webhooks Webhook[]
siteSettings SiteSettings[]
@@index([email])
}
@ -115,6 +117,23 @@ model Webhook {
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
enum ApiTokenAlgorithm {
SHA512
}
model ApiToken {
id Int @id @default(autoincrement())
name String
token String @unique
algorithm ApiTokenAlgorithm @default(SHA512)
expires DateTime?
createdAt DateTime @default(now())
userId Int?
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
teamId Int?
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
}
enum SubscriptionStatus {
ACTIVE
PAST_DUE
@ -378,6 +397,7 @@ model Team {
document Document[]
templates Template[]
ApiToken ApiToken[]
}
model TeamPending {
@ -471,3 +491,12 @@ model Template {
@@unique([templateDocumentDataId])
}
model SiteSettings {
id String @id
enabled Boolean @default(false)
data Json
lastModifiedByUserId Int?
lastModifiedAt DateTime @default(now())
lastModifiedByUser User? @relation(fields: [lastModifiedByUserId], references: [id])
}

View File

@ -2,7 +2,7 @@ import fs from 'node:fs';
import path from 'node:path';
import { prisma } from '..';
import { DocumentDataType } from '../client';
import { DocumentDataType, ReadStatus, RecipientRole, SendStatus, SigningStatus } from '../client';
const examplePdf = fs
.readFileSync(path.join(__dirname, '../../../assets/example.pdf'))
@ -28,9 +28,36 @@ export const seedTemplate = async (options: SeedTemplateOptions) => {
return await prisma.template.create({
data: {
title,
templateDocumentDataId: documentData.id,
userId: userId,
teamId,
templateDocumentData: {
connect: {
id: documentData.id,
},
},
User: {
connect: {
id: userId,
},
},
Recipient: {
create: {
email: 'recipient.1@documenso.com',
name: 'Recipient 1',
token: Math.random().toString().slice(2, 7),
sendStatus: SendStatus.NOT_SENT,
signingStatus: SigningStatus.NOT_SIGNED,
readStatus: ReadStatus.NOT_OPENED,
role: RecipientRole.SIGNER,
},
},
...(teamId
? {
team: {
connect: {
id: teamId,
},
},
}
: {}),
},
});
};

View File

@ -32,3 +32,22 @@ export const unseedUser = async (userId: number) => {
},
});
};
export const unseedUserByEmail = async (email: string) => {
await prisma.user.delete({
where: {
email,
},
});
};
export const extractUserVerificationToken = async (email: string) => {
return await prisma.verificationToken.findFirstOrThrow({
where: {
identifier: 'confirmation-email',
user: {
email,
},
},
});
};