From ae9165087e01a0b1b154be493d80ed917bd375fc Mon Sep 17 00:00:00 2001 From: Gautier Darchen Date: Fri, 27 Oct 2023 14:25:43 +0200 Subject: [PATCH] feat(core): Enable setting different cookie name for Shop & Admin API (#2482) --- packages/common/src/shared-constants.ts | 3 ++- packages/core/src/bootstrap.ts | 26 ++++++++++++++++++++-- packages/core/src/config/vendure-config.ts | 6 +++-- packages/testing/src/test-server.ts | 6 ++--- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/common/src/shared-constants.ts b/packages/common/src/shared-constants.ts index fb84aaee9c..b2d9490845 100644 --- a/packages/common/src/shared-constants.ts +++ b/packages/common/src/shared-constants.ts @@ -14,7 +14,8 @@ export const CUSTOMER_ROLE_CODE = '__customer_role__'; export const CUSTOMER_ROLE_DESCRIPTION = 'Customer'; export const ROOT_COLLECTION_NAME = '__root_collection__'; export const DEFAULT_AUTH_TOKEN_HEADER_KEY = 'vendure-auth-token'; -export const DEFAULT_CHANNEL_TOKEN_KEY = 'vendure-token' +export const DEFAULT_COOKIE_NAME = 'session'; +export const DEFAULT_CHANNEL_TOKEN_KEY = 'vendure-token'; // An environment variable which is set when the @vendure/create // script is run. Can be used to modify normal behaviour diff --git a/packages/core/src/bootstrap.ts b/packages/core/src/bootstrap.ts index b4cb6c5e87..bd61ce956e 100644 --- a/packages/core/src/bootstrap.ts +++ b/packages/core/src/bootstrap.ts @@ -1,6 +1,7 @@ import { INestApplication, INestApplicationContext } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { getConnectionToken } from '@nestjs/typeorm'; +import { DEFAULT_COOKIE_NAME } from '@vendure/common/lib/shared-constants'; import { Type } from '@vendure/common/lib/shared-types'; import cookieSession = require('cookie-session'); import { satisfies } from 'semver'; @@ -64,8 +65,7 @@ export async function bootstrap(userConfig: Partial): Promise mid.beforeListen); earlyMiddlewares.forEach(mid => { @@ -329,3 +329,25 @@ async function validateDbTablesForWorker(worker: INestApplicationContext) { reject('Could not validate DB table structure. Aborting bootstrap.'); }); } + +export function configureSessionCookies( + app: INestApplication, + userConfig: Readonly, +): void { + const { cookieOptions } = userConfig.authOptions; + app.use( + cookieSession({ + ...cookieOptions, + name: typeof cookieOptions?.name === 'string' ? cookieOptions.name : DEFAULT_COOKIE_NAME, + }), + ); + + // If the Admin API and Shop API should have specific cookies names + if (typeof cookieOptions?.name === 'object') { + const shopApiCookieName = cookieOptions.name.shop; + const adminApiCookieName = cookieOptions.name.admin; + const { shopApiPath, adminApiPath } = userConfig.apiOptions; + app.use(`/${shopApiPath}`, cookieSession({ ...cookieOptions, name: shopApiCookieName })); + app.use(`/${adminApiPath}`, cookieSession({ ...cookieOptions, name: adminApiCookieName })); + } +} diff --git a/packages/core/src/config/vendure-config.ts b/packages/core/src/config/vendure-config.ts index a7a38e3238..64a7fad493 100644 --- a/packages/core/src/config/vendure-config.ts +++ b/packages/core/src/config/vendure-config.ts @@ -221,11 +221,13 @@ export interface ApiOptions { export interface CookieOptions { /** * @description - * The name of the cookie to set. + * The name of the cookies to set. + * If set to a string, both cookies for the Admin API and Shop API will have the same name. + * If set as an object, it makes it possible to give different names to the Admin API and the Shop API cookies * * @default 'session' */ - name?: string; + name?: string | { shop: string; admin: string }; /** * @description diff --git a/packages/testing/src/test-server.ts b/packages/testing/src/test-server.ts index d6fc69b6c3..8f90a7263a 100644 --- a/packages/testing/src/test-server.ts +++ b/packages/testing/src/test-server.ts @@ -1,8 +1,7 @@ import { INestApplication } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { DefaultLogger, JobQueueService, Logger, VendureConfig } from '@vendure/core'; -import { preBootstrapConfig } from '@vendure/core/dist/bootstrap'; -import cookieSession from 'cookie-session'; +import { preBootstrapConfig, configureSessionCookies } from '@vendure/core/dist/bootstrap'; import { populateForTesting } from './data-population/populate-for-testing'; import { getInitializerFor } from './initializers/initializers'; @@ -121,8 +120,7 @@ export class TestServer { const usingCookie = tokenMethod === 'cookie' || (Array.isArray(tokenMethod) && tokenMethod.includes('cookie')); if (usingCookie) { - const { cookieOptions } = config.authOptions; - app.use(cookieSession(cookieOptions)); + configureSessionCookies(app, config); } const earlyMiddlewares = config.apiOptions.middleware.filter(mid => mid.beforeListen); earlyMiddlewares.forEach(mid => {