Преглед изворни кода

fix(cookies): Apply split cookie session middleware per route (#2880)

Gautier Darchen пре 1 година
родитељ
комит
37de9f459d
2 измењених фајлова са 32 додато и 11 уклоњено
  1. 28 1
      packages/core/src/app.module.ts
  2. 4 10
      packages/core/src/bootstrap.ts

+ 28 - 1
packages/core/src/app.module.ts

@@ -1,4 +1,5 @@
 import { MiddlewareConsumer, Module, NestModule, OnApplicationShutdown } from '@nestjs/common';
+import cookieSession from 'cookie-session';
 
 import { ApiModule } from './api/api.module';
 import { Middleware, MiddlewareHandler } from './common';
@@ -26,18 +27,44 @@ import { ServiceModule } from './service/service.module';
     ],
 })
 export class AppModule implements NestModule, OnApplicationShutdown {
-    constructor(private configService: ConfigService, private i18nService: I18nService) {}
+    constructor(
+        private configService: ConfigService,
+        private i18nService: I18nService,
+    ) {}
 
     configure(consumer: MiddlewareConsumer) {
         const { adminApiPath, shopApiPath, middleware } = this.configService.apiOptions;
+        const { cookieOptions } = this.configService.authOptions;
+
         const i18nextHandler = this.i18nService.handle();
         const defaultMiddleware: Middleware[] = [
             { handler: i18nextHandler, route: adminApiPath },
             { handler: i18nextHandler, route: shopApiPath },
         ];
+
         const allMiddleware = defaultMiddleware.concat(middleware);
+
+        // If the Admin API and Shop API should have specific cookies names, we need to create separate cookie sessions
+        if (typeof cookieOptions?.name === 'object') {
+            const shopApiCookieName = cookieOptions.name.shop;
+            const adminApiCookieName = cookieOptions.name.admin;
+            allMiddleware.push({
+                handler: cookieSession({ ...cookieOptions, name: adminApiCookieName }),
+                route: adminApiPath,
+            });
+            allMiddleware.push({
+                handler: cookieSession({ ...cookieOptions, name: shopApiCookieName }),
+                route: shopApiPath,
+            });
+            allMiddleware.push({
+                handler: cookieSession({ ...cookieOptions, name: shopApiCookieName }),
+                route: '/',
+            });
+        }
+
         const consumableMiddlewares = allMiddleware.filter(mid => !mid.beforeListen);
         const middlewareByRoute = this.groupMiddlewareByRoute(consumableMiddlewares);
+
         for (const [route, handlers] of Object.entries(middlewareByRoute)) {
             consumer.apply(...handlers).forRoutes(route);
         }

+ 4 - 10
packages/core/src/bootstrap.ts

@@ -250,7 +250,7 @@ function checkPluginCompatibility(config: RuntimeVendureConfig): void {
             if (!satisfies(VENDURE_VERSION, compatibility, { loose: true, includePrerelease: true })) {
                 Logger.error(
                     `Plugin "${pluginName}" is not compatible with this version of Vendure. ` +
-                    `It specifies a semver range of "${compatibility}" but the current version is "${VENDURE_VERSION}".`,
+                        `It specifies a semver range of "${compatibility}" but the current version is "${VENDURE_VERSION}".`,
                 );
                 throw new InternalServerError(
                     `Plugin "${pluginName}" is not compatible with this version of Vendure.`,
@@ -411,15 +411,9 @@ export function configureSessionCookies(
 ): void {
     const { cookieOptions } = userConfig.authOptions;
 
-    // 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(cookieSession({...cookieOptions, name: shopApiCookieName}));
-        app.use(`/${shopApiPath}`, cookieSession({ ...cookieOptions, name: shopApiCookieName }));
-        app.use(`/${adminApiPath}`, cookieSession({ ...cookieOptions, name: adminApiCookieName }));
-    } else {
+    // If the Admin API and Shop API should have the same cookie name
+    // Else, the specific cookie middlewares are handled in the 'AppModule#configure' method
+    if (typeof cookieOptions?.name === 'string') {
         app.use(
             cookieSession({
                 ...cookieOptions,