fix: add sign up hook
This commit is contained in:
@@ -81,27 +81,7 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
throw redirect(documentRootPath);
|
throw redirect(documentRootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { documentMeta } = document;
|
// Todo: Get full document instead?
|
||||||
|
|
||||||
// Todo: We don't handle encrypted files right.
|
|
||||||
// if (documentMeta?.password) {
|
|
||||||
// const key = DOCUMENSO_ENCRYPTION_KEY;
|
|
||||||
|
|
||||||
// if (!key) {
|
|
||||||
// throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const securePassword = Buffer.from(
|
|
||||||
// symmetricDecrypt({
|
|
||||||
// key,
|
|
||||||
// data: documentMeta.password,
|
|
||||||
// }),
|
|
||||||
// ).toString('utf-8');
|
|
||||||
|
|
||||||
// documentMeta.password = securePassword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Todo: Get full document instead???
|
|
||||||
const [recipients, fields] = await Promise.all([
|
const [recipients, fields] = await Promise.all([
|
||||||
getRecipientsForDocument({
|
getRecipientsForDocument({
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@@ -68,24 +68,6 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
throw redirect(`${documentRootPath}/${documentId}`);
|
throw redirect(`${documentRootPath}/${documentId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: We don't handle encrypted files right.
|
|
||||||
// if (documentMeta?.password) {
|
|
||||||
// const key = DOCUMENSO_ENCRYPTION_KEY;
|
|
||||||
|
|
||||||
// if (!key) {
|
|
||||||
// throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const securePassword = Buffer.from(
|
|
||||||
// symmetricDecrypt({
|
|
||||||
// key,
|
|
||||||
// data: documentMeta.password,
|
|
||||||
// }),
|
|
||||||
// ).toString('utf-8');
|
|
||||||
|
|
||||||
// documentMeta.password = securePassword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const isDocumentEnterprise = await isUserEnterprise({
|
const isDocumentEnterprise = await isUserEnterprise({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: team?.id,
|
teamId: team?.id,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
throw redirect(documentRootPath);
|
throw redirect(documentRootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Get detailed?
|
// Todo: Get full document instead?
|
||||||
const [document, recipients] = await Promise.all([
|
const [document, recipients] = await Promise.all([
|
||||||
getDocumentById({
|
getDocumentById({
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@@ -118,24 +118,6 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
throw redirect(documentMeta?.redirectUrl || `/sign/${token}/complete`);
|
throw redirect(documentMeta?.redirectUrl || `/sign/${token}/complete`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: We don't handle encrypted files right.
|
|
||||||
// if (documentMeta?.password) {
|
|
||||||
// const key = DOCUMENSO_ENCRYPTION_KEY;
|
|
||||||
|
|
||||||
// if (!key) {
|
|
||||||
// throw new Error('Missing DOCUMENSO_ENCRYPTION_KEY');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const securePassword = Buffer.from(
|
|
||||||
// symmetricDecrypt({
|
|
||||||
// key,
|
|
||||||
// data: documentMeta.password,
|
|
||||||
// }),
|
|
||||||
// ).toString('utf-8');
|
|
||||||
|
|
||||||
// documentMeta.password = securePassword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const [recipientSignature] = await getRecipientSignatures({ recipientId: recipient.id });
|
const [recipientSignature] = await getRecipientSignatures({ recipientId: recipient.id });
|
||||||
|
|
||||||
return superLoaderJson({
|
return superLoaderJson({
|
||||||
|
|||||||
@@ -33,11 +33,6 @@ export const filesRoute = new Hono<HonoEnv>()
|
|||||||
return c.json({ error: 'No file provided' }, 400);
|
return c.json({ error: 'No file provided' }, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Do we want to validate the file type?
|
|
||||||
// if (file.type !== 'application/pdf') {
|
|
||||||
// return c.json({ error: 'File must be a PDF' }, 400);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Todo: This is new.
|
// Todo: This is new.
|
||||||
// Add file size validation.
|
// Add file size validation.
|
||||||
// Convert MB to bytes (1 MB = 1024 * 1024 bytes)
|
// Convert MB to bytes (1 MB = 1024 * 1024 bytes)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import {
|
|||||||
type RequestMetadata,
|
type RequestMetadata,
|
||||||
extractRequestMetadata,
|
extractRequestMetadata,
|
||||||
} from '@documenso/lib/universal/extract-request-metadata';
|
} from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { AppLogger } from '@documenso/lib/utils/debugger';
|
import { AppDebugger } from '@documenso/lib/utils/debugger';
|
||||||
|
|
||||||
const logger = new AppLogger('Middleware');
|
const debug = new AppDebugger('Middleware');
|
||||||
|
|
||||||
export type AppContext = {
|
export type AppContext = {
|
||||||
requestMetadata: RequestMetadata;
|
requestMetadata: RequestMetadata;
|
||||||
@@ -27,7 +27,7 @@ export const appContext = async (c: Context, next: Next) => {
|
|||||||
const noSessionCookie = extractSessionCookieFromHeaders(request.headers) === null;
|
const noSessionCookie = extractSessionCookieFromHeaders(request.headers) === null;
|
||||||
|
|
||||||
if (!isPageRequest(request) || noSessionCookie || blacklistedPathsRegex.test(url.pathname)) {
|
if (!isPageRequest(request) || noSessionCookie || blacklistedPathsRegex.test(url.pathname)) {
|
||||||
// logger.log('Pathname ignored', url.pathname);
|
// debug.log('Pathname ignored', url.pathname);
|
||||||
|
|
||||||
setAppContext(c, {
|
setAppContext(c, {
|
||||||
requestMetadata: extractRequestMetadata(request),
|
requestMetadata: extractRequestMetadata(request),
|
||||||
@@ -61,7 +61,7 @@ export const appContext = async (c: Context, next: Next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const endTime = Date.now();
|
const endTime = Date.now();
|
||||||
logger.log(`Pathname accepted in ${endTime - initTime}ms`, url.pathname);
|
debug.log(`Pathname accepted in ${endTime - initTime}ms`, url.pathname);
|
||||||
|
|
||||||
setAppContext(c, {
|
setAppContext(c, {
|
||||||
requestMetadata: extractRequestMetadata(request),
|
requestMetadata: extractRequestMetadata(request),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { Context, Next } from 'hono';
|
import type { Context, Next } from 'hono';
|
||||||
import { getCookie } from 'hono/cookie';
|
import { getCookie } from 'hono/cookie';
|
||||||
|
|
||||||
import { AppLogger } from '@documenso/lib/utils/debugger';
|
import { AppDebugger } from '@documenso/lib/utils/debugger';
|
||||||
|
|
||||||
const logger = new AppLogger('Middleware');
|
const debug = new AppDebugger('Middleware');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware for initial page loads.
|
* Middleware for initial page loads.
|
||||||
@@ -23,7 +23,7 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log('Path', path);
|
debug.log('Path', path);
|
||||||
|
|
||||||
const preferredTeamUrl = getCookie(c, 'preferred-team-url');
|
const preferredTeamUrl = getCookie(c, 'preferred-team-url');
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
|
|
||||||
// // Redirect root page to `/documents` or `/t/{preferredTeamUrl}/documents`.
|
// // Redirect root page to `/documents` or `/t/{preferredTeamUrl}/documents`.
|
||||||
// if (path === '/') {
|
// if (path === '/') {
|
||||||
// logger.log('Redirecting from root to documents');
|
// debug.log('Redirecting from root to documents');
|
||||||
|
|
||||||
// const redirectUrlPath = formatDocumentsPath(
|
// const redirectUrlPath = formatDocumentsPath(
|
||||||
// resetPreferredTeamUrl ? undefined : preferredTeamUrl,
|
// resetPreferredTeamUrl ? undefined : preferredTeamUrl,
|
||||||
@@ -58,7 +58,7 @@ export const appMiddleware = async (c: Context, next: Next) => {
|
|||||||
|
|
||||||
// // Clear preferred team url cookie if user accesses a non team page from a team page.
|
// // Clear preferred team url cookie if user accesses a non team page from a team page.
|
||||||
// if (resetPreferredTeamUrl || path === '/documents') {
|
// if (resetPreferredTeamUrl || path === '/documents') {
|
||||||
// logger.log('Resetting preferred team url');
|
// debug.log('Resetting preferred team url');
|
||||||
|
|
||||||
// deleteCookie(c, 'preferred-team-url');
|
// deleteCookie(c, 'preferred-team-url');
|
||||||
// return next();
|
// return next();
|
||||||
|
|||||||
@@ -4,16 +4,6 @@ import { createTrpcContext } from '@documenso/trpc/server/context';
|
|||||||
import { appRouter } from '@documenso/trpc/server/router';
|
import { appRouter } from '@documenso/trpc/server/router';
|
||||||
import { handleTrpcRouterError } from '@documenso/trpc/utils/trpc-error-handler';
|
import { handleTrpcRouterError } from '@documenso/trpc/utils/trpc-error-handler';
|
||||||
|
|
||||||
// Todo
|
|
||||||
// export const config = {
|
|
||||||
// maxDuration: 120,
|
|
||||||
// api: {
|
|
||||||
// bodyParser: {
|
|
||||||
// sizeLimit: '50mb',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trpc server for internal routes like /api/trpc/*
|
* Trpc server for internal routes like /api/trpc/*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,12 +19,4 @@ export const onAuthorize = async (user: AuthorizeUser, c: Context<HonoAuthContex
|
|||||||
await createSession(sessionToken, user.userId, metadata);
|
await createSession(sessionToken, user.userId, metadata);
|
||||||
|
|
||||||
await setSessionCookie(c, sessionToken);
|
await setSessionCookie(c, sessionToken);
|
||||||
|
|
||||||
// Todo.
|
|
||||||
// Create the Stripe customer and attach it to the user if it doesn't exist.
|
|
||||||
// if (user.customerId === null && IS_BILLING_ENABLED()) {
|
|
||||||
// await getStripeCustomerByUser(user).catch((err) => {
|
|
||||||
// console.error(err);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
|
import { onCreateUserHook } from '@documenso/lib/server-only/user/create-user';
|
||||||
import { env } from '@documenso/lib/utils/env';
|
import { env } from '@documenso/lib/utils/env';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
||||||
@@ -232,6 +233,11 @@ export const googleRoute = new Hono<HonoAuthContext>()
|
|||||||
return user;
|
return user;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await onCreateUserHook(createdUser).catch((err) => {
|
||||||
|
// Todo: Add logging.
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
await onAuthorize({ userId: createdUser.id }, c);
|
await onAuthorize({ userId: createdUser.id }, c);
|
||||||
|
|
||||||
return c.redirect(redirectPath, 302);
|
return c.redirect(redirectPath, 302);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { hash } from '@node-rs/bcrypt';
|
import { hash } from '@node-rs/bcrypt';
|
||||||
|
import type { User } from '@prisma/client';
|
||||||
import { TeamMemberInviteStatus } from '@prisma/client';
|
import { TeamMemberInviteStatus } from '@prisma/client';
|
||||||
|
|
||||||
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
|
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
|
||||||
@@ -70,6 +71,22 @@ export const createUser = async ({ name, email, password, signature, url }: Crea
|
|||||||
return user;
|
return user;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await onCreateUserHook(user).catch((err) => {
|
||||||
|
// Todo: Add logging.
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
return user;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should be run after a user is created.
|
||||||
|
*
|
||||||
|
* @returns User
|
||||||
|
*/
|
||||||
|
export const onCreateUserHook = async (user: User) => {
|
||||||
|
const { email } = user;
|
||||||
|
|
||||||
const acceptedTeamInvites = await prisma.teamMemberInvite.findMany({
|
const acceptedTeamInvites = await prisma.teamMemberInvite.findMany({
|
||||||
where: {
|
where: {
|
||||||
status: TeamMemberInviteStatus.ACCEPTED,
|
status: TeamMemberInviteStatus.ACCEPTED,
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
export const appLog = (context: string, ...args: Parameters<typeof console.log>) => {
|
import { env } from './env';
|
||||||
// if (env('NEXT_DEBUG') === 'true') {
|
|
||||||
console.log(`[${context}]: ${args[0]}`, ...args.slice(1));
|
/**
|
||||||
// }
|
* Which areas to debug, keyed by context.
|
||||||
|
*/
|
||||||
|
const debugging: Record<string, boolean> = {
|
||||||
|
auth: env('NEXT_DEBUG_AUTH') === 'true',
|
||||||
|
job: env('NEXT_DEBUG_JOB') === 'true',
|
||||||
|
middleware: env('NEXT_DEBUG_MIDDLEWARE') === 'true',
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AppLogger {
|
export const appLog = (context: string, ...args: Parameters<typeof console.log>) => {
|
||||||
|
if (debugging[context.toLowerCase()] === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env('NEXT_DEBUG') === 'true') {
|
||||||
|
console.log(`[${context}]: ${args[0]}`, ...args.slice(1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export class AppDebugger {
|
||||||
public context: string;
|
public context: string;
|
||||||
|
|
||||||
constructor(context: string) {
|
constructor(context: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user