Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/silver-items-tie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": patch
---

Adds the `__Secure-` prefix to the add additional broswer security policies around this cookie.
24 changes: 18 additions & 6 deletions core/auth/anonymous-session.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import { cookies } from 'next/headers';
import { cookies, headers } from 'next/headers';
import { AnonymousUser } from 'next-auth';
import { decode, encode } from 'next-auth/jwt';

const anonymousCookieName = 'authjs.anonymous-session-token';

const shouldUseSecureCookie = async () => {
const headersList = await headers();

return headersList.get('x-forwarded-proto') === 'https';
};

export const anonymousSignIn = async (user: Partial<AnonymousUser> = { cartId: null }) => {
const secret = process.env.AUTH_SECRET ?? process.env.NEXTAUTH_SECRET;
const useSecureCookies = await shouldUseSecureCookie();
const cookiePrefix = useSecureCookies ? '__Secure-' : '';

if (!secret) {
throw new Error('AUTH_SECRET is not set');
}

const cookieJar = await cookies();
const jwt = await encode({
salt: anonymousCookieName,
salt: `${cookiePrefix}${anonymousCookieName}`,
secret,
token: {
user,
},
});

cookieJar.set(anonymousCookieName, jwt, {
cookieJar.set(`${cookiePrefix}${anonymousCookieName}`, jwt, {
secure: true,
sameSite: 'lax',
// We set the maxAge to 7 days as a good default for anonymous sessions.
Expand All @@ -32,7 +40,9 @@ export const anonymousSignIn = async (user: Partial<AnonymousUser> = { cartId: n

export const getAnonymousSession = async () => {
const cookieJar = await cookies();
const jwt = cookieJar.get(anonymousCookieName);
const useSecureCookies = await shouldUseSecureCookie();
const cookiePrefix = useSecureCookies ? '__Secure-' : '';
const jwt = cookieJar.get(`${cookiePrefix}${anonymousCookieName}`);

if (!jwt) {
return null;
Expand All @@ -46,7 +56,7 @@ export const getAnonymousSession = async () => {

const session = await decode({
secret,
salt: anonymousCookieName,
salt: `${cookiePrefix}${anonymousCookieName}`,
token: jwt.value,
});

Expand All @@ -55,8 +65,10 @@ export const getAnonymousSession = async () => {

export const clearAnonymousSession = async () => {
const cookieJar = await cookies();
const useSecureCookies = await shouldUseSecureCookie();
const cookiePrefix = useSecureCookies ? '__Secure-' : '';

cookieJar.delete(anonymousCookieName);
cookieJar.delete(`${cookiePrefix}${anonymousCookieName}`);
};

export const updateAnonymousSession = async (user: AnonymousUser) => {
Expand Down