mirror of
https://github.com/documenso/documenso.git
synced 2026-07-26 01:45:08 +10:00
fix: security improvements (#2593)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZNameSchema } from '@documenso/lib/constants/auth';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
|
||||
export const ZCurrentPasswordSchema = z
|
||||
@@ -36,7 +37,7 @@ export const ZPasswordSchema = z
|
||||
});
|
||||
|
||||
export const ZSignUpSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
name: ZNameSchema,
|
||||
email: zEmail(),
|
||||
password: ZPasswordSchema,
|
||||
signature: z.string().nullish(),
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { env } from '../utils/env';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from './app';
|
||||
|
||||
export const SALT_ROUNDS = 12;
|
||||
|
||||
export const URL_PATTERN = /https?:\/\/|www\./i;
|
||||
|
||||
/**
|
||||
* Shared name schema that disallows URLs to prevent phishing via email rendering.
|
||||
*/
|
||||
export const ZNameSchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(3, { message: 'Please enter a valid name.' })
|
||||
.refine((value) => !URL_PATTERN.test(value), {
|
||||
message: 'Name cannot contain URLs.',
|
||||
});
|
||||
|
||||
export const IDENTITY_PROVIDER_NAME: Record<string, string> = {
|
||||
DOCUMENSO: 'Documenso',
|
||||
GOOGLE: 'Google',
|
||||
|
||||
@@ -2,7 +2,7 @@ import crypto from 'crypto';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { ONE_DAY } from '../../constants/time';
|
||||
import { ONE_HOUR } from '../../constants/time';
|
||||
import { sendForgotPassword } from '../auth/send-forgot-password';
|
||||
|
||||
export const forgotPassword = async ({ email }: { email: string }) => {
|
||||
@@ -41,7 +41,7 @@ export const forgotPassword = async ({ email }: { email: string }) => {
|
||||
await prisma.passwordResetToken.create({
|
||||
data: {
|
||||
token,
|
||||
expiry: new Date(Date.now() + ONE_DAY),
|
||||
expiry: new Date(Date.now() + ONE_HOUR),
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -54,6 +54,12 @@ export const updatePassword = async ({
|
||||
},
|
||||
});
|
||||
|
||||
await tx.passwordResetToken.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
|
||||
return await tx.user.update({
|
||||
where: {
|
||||
id: userId,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZNameSchema } from '@documenso/lib/constants/auth';
|
||||
|
||||
export const ZFindUserSecurityAuditLogsSchema = z.object({
|
||||
page: z.number().optional(),
|
||||
perPage: z.number().optional(),
|
||||
@@ -8,7 +10,7 @@ export const ZFindUserSecurityAuditLogsSchema = z.object({
|
||||
export type TFindUserSecurityAuditLogsSchema = z.infer<typeof ZFindUserSecurityAuditLogsSchema>;
|
||||
|
||||
export const ZUpdateProfileMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
name: ZNameSchema,
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TeamMemberRole } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { URL_PATTERN, ZNameSchema } from '@documenso/lib/constants/auth';
|
||||
import { PROTECTED_TEAM_URLS } from '@documenso/lib/constants/teams';
|
||||
import { zEmail } from '@documenso/lib/utils/zod';
|
||||
|
||||
@@ -39,11 +40,14 @@ export const ZTeamNameSchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(3, { message: 'Team name must be at least 3 characters long.' })
|
||||
.max(30, { message: 'Team name must not exceed 30 characters.' });
|
||||
.max(30, { message: 'Team name must not exceed 30 characters.' })
|
||||
.refine((value) => !URL_PATTERN.test(value), {
|
||||
message: 'Team name cannot contain URLs.',
|
||||
});
|
||||
|
||||
export const ZCreateTeamEmailVerificationMutationSchema = z.object({
|
||||
teamId: z.number(),
|
||||
name: z.string().trim().min(1, { message: 'Please enter a valid name.' }),
|
||||
name: ZNameSchema,
|
||||
email: zEmail().trim().toLowerCase().min(1, 'Please enter a valid email.'),
|
||||
});
|
||||
|
||||
@@ -62,7 +66,7 @@ export const ZGetTeamMembersQuerySchema = z.object({
|
||||
export const ZUpdateTeamEmailMutationSchema = z.object({
|
||||
teamId: z.number(),
|
||||
data: z.object({
|
||||
name: z.string().trim().min(1),
|
||||
name: ZNameSchema,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user