mirror of
https://github.com/documenso/documenso.git
synced 2025-11-11 13:02:31 +10:00
fix: secure passkey cookies (#1533)
This commit is contained in:
@ -46,3 +46,10 @@ export const PASSKEY_TIMEOUT = 60000;
|
|||||||
* The maximum number of passkeys are user can have.
|
* The maximum number of passkeys are user can have.
|
||||||
*/
|
*/
|
||||||
export const MAXIMUM_PASSKEYS = 50;
|
export const MAXIMUM_PASSKEYS = 50;
|
||||||
|
|
||||||
|
export const useSecureCookies =
|
||||||
|
process.env.NODE_ENV === 'production' && String(process.env.NEXTAUTH_URL).startsWith('https://');
|
||||||
|
|
||||||
|
const secureCookiePrefix = useSecureCookies ? '__Secure-' : '';
|
||||||
|
|
||||||
|
export const formatSecureCookieName = (name: string) => `${secureCookiePrefix}${name}`;
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { env } from 'next-runtime-env';
|
|||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { IdentityProvider, UserSecurityAuditLogType } from '@documenso/prisma/client';
|
import { IdentityProvider, UserSecurityAuditLogType } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
import { formatSecureCookieName, useSecureCookies } from '../constants/auth';
|
||||||
import { AppError, AppErrorCode } from '../errors/app-error';
|
import { AppError, AppErrorCode } from '../errors/app-error';
|
||||||
import { jobsClient } from '../jobs/client';
|
import { jobsClient } from '../jobs/client';
|
||||||
import { isTwoFactorAuthenticationEnabled } from '../server-only/2fa/is-2fa-availble';
|
import { isTwoFactorAuthenticationEnabled } from '../server-only/2fa/is-2fa-availble';
|
||||||
@ -26,10 +27,6 @@ import { extractNextAuthRequestMetadata } from '../universal/extract-request-met
|
|||||||
import { getAuthenticatorOptions } from '../utils/authenticator';
|
import { getAuthenticatorOptions } from '../utils/authenticator';
|
||||||
import { ErrorCode } from './error-codes';
|
import { ErrorCode } from './error-codes';
|
||||||
|
|
||||||
const useSecureCookies =
|
|
||||||
process.env.NODE_ENV === 'production' && String(process.env.NEXTAUTH_URL).startsWith('https://');
|
|
||||||
const cookiePrefix = useSecureCookies ? '__Secure-' : '';
|
|
||||||
|
|
||||||
export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
||||||
adapter: PrismaAdapter(prisma),
|
adapter: PrismaAdapter(prisma),
|
||||||
secret: process.env.NEXTAUTH_SECRET ?? 'secret',
|
secret: process.env.NEXTAUTH_SECRET ?? 'secret',
|
||||||
@ -437,7 +434,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
},
|
},
|
||||||
cookies: {
|
cookies: {
|
||||||
sessionToken: {
|
sessionToken: {
|
||||||
name: `${cookiePrefix}next-auth.session-token`,
|
name: formatSecureCookieName('next-auth.session-token'),
|
||||||
options: {
|
options: {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax',
|
||||||
@ -446,7 +443,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
callbackUrl: {
|
callbackUrl: {
|
||||||
name: `${cookiePrefix}next-auth.callback-url`,
|
name: formatSecureCookieName('next-auth.callback-url'),
|
||||||
options: {
|
options: {
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax',
|
||||||
path: '/',
|
path: '/',
|
||||||
@ -456,7 +453,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
csrfToken: {
|
csrfToken: {
|
||||||
// Default to __Host- for CSRF token for additional protection if using useSecureCookies
|
// Default to __Host- for CSRF token for additional protection if using useSecureCookies
|
||||||
// NB: The `__Host-` prefix is stricter than the `__Secure-` prefix.
|
// NB: The `__Host-` prefix is stricter than the `__Secure-` prefix.
|
||||||
name: `${cookiePrefix}next-auth.csrf-token`,
|
name: formatSecureCookieName('next-auth.csrf-token'),
|
||||||
options: {
|
options: {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax',
|
||||||
@ -465,7 +462,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
pkceCodeVerifier: {
|
pkceCodeVerifier: {
|
||||||
name: `${cookiePrefix}next-auth.pkce.code_verifier`,
|
name: formatSecureCookieName('next-auth.pkce.code_verifier'),
|
||||||
options: {
|
options: {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax',
|
||||||
@ -474,7 +471,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
name: `${cookiePrefix}next-auth.state`,
|
name: formatSecureCookieName('next-auth.state'),
|
||||||
options: {
|
options: {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: useSecureCookies ? 'none' : 'lax',
|
sameSite: useSecureCookies ? 'none' : 'lax',
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { parse } from 'cookie-es';
|
|||||||
import { env } from 'next-runtime-env';
|
import { env } from 'next-runtime-env';
|
||||||
|
|
||||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||||
|
import { formatSecureCookieName } from '@documenso/lib/constants/auth';
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { jobsClient } from '@documenso/lib/jobs/client';
|
import { jobsClient } from '@documenso/lib/jobs/client';
|
||||||
import { ErrorCode } from '@documenso/lib/next-auth/error-codes';
|
import { ErrorCode } from '@documenso/lib/next-auth/error-codes';
|
||||||
@ -111,7 +112,8 @@ export const authRouter = router({
|
|||||||
const cookies = parse(ctx.req.headers.cookie ?? '');
|
const cookies = parse(ctx.req.headers.cookie ?? '');
|
||||||
|
|
||||||
const sessionIdToken =
|
const sessionIdToken =
|
||||||
cookies['__Host-next-auth.csrf-token'] || cookies['next-auth.csrf-token'];
|
cookies[formatSecureCookieName('__Host-next-auth.csrf-token')] ||
|
||||||
|
cookies[formatSecureCookieName('next-auth.csrf-token')];
|
||||||
|
|
||||||
if (!sessionIdToken) {
|
if (!sessionIdToken) {
|
||||||
throw new Error('Missing CSRF token');
|
throw new Error('Missing CSRF token');
|
||||||
|
|||||||
Reference in New Issue
Block a user