Răsfoiți Sursa

feat(core): Expose all cookie options in VendureConfig

Closes #436
Michael Bromley 5 ani în urmă
părinte
comite
ad089eac48

+ 8 - 6
packages/core/src/bootstrap.ts

@@ -56,12 +56,14 @@ export async function bootstrap(userConfig: Partial<VendureConfig>): Promise<INe
     app.useLogger(new Logger());
     await runBeforeBootstrapHooks(config, app);
     if (config.authOptions.tokenMethod === 'cookie') {
-        const cookieHandler = cookieSession({
-            name: 'session',
-            secret: config.authOptions.sessionSecret,
-            httpOnly: true,
-        });
-        app.use(cookieHandler);
+        const { sessionSecret, cookieOptions } = config.authOptions;
+        app.use(
+            cookieSession({
+                ...cookieOptions,
+                // TODO: Remove once the deprecated sessionSecret field is removed
+                ...(sessionSecret ? { secret: sessionSecret } : {}),
+            }),
+        );
     }
     await app.listen(port, hostname || '');
     app.enableShutdownHooks();

+ 7 - 1
packages/core/src/config/default-config.ts

@@ -59,7 +59,13 @@ export const defaultConfig: RuntimeVendureConfig = {
     authOptions: {
         disableAuth: false,
         tokenMethod: 'cookie',
-        sessionSecret: 'session-secret',
+        sessionSecret: '',
+        cookieOptions: {
+            secret: Math.random()
+                .toString(36)
+                .substr(3),
+            httpOnly: true,
+        },
         authTokenHeaderKey: DEFAULT_AUTH_TOKEN_HEADER_KEY,
         sessionDuration: '1y',
         sessionCacheStrategy: new InMemorySessionCacheStrategy(),

+ 92 - 0
packages/core/src/config/vendure-config.ts

@@ -137,6 +137,90 @@ export interface ApiOptions {
     apolloServerPlugins?: PluginDefinition[];
 }
 
+/**
+ * @description
+ * Options for the handling of the cookies used to track sessions (only applicable if
+ * `authOptions.tokenMethod` is set to `'cookie'`). These options are passed directly
+ * to the Express [cookie-session middleware](https://github.com/expressjs/cookie-session).
+ *
+ * @docsCategory auth
+ */
+export interface CookieOptions {
+    /**
+     * @description
+     * The name of the cookie to set.
+     *
+     * @default 'session'
+     */
+    name?: string;
+
+    /**
+     * @description
+     * A string which will be used as single key if keys is not provided.
+     *
+     * @default (random character string)
+     */
+    secret?: string;
+
+    /**
+     * @description
+     * a string indicating the path of the cookie.
+     *
+     * @default '/'
+     */
+    path?: string;
+
+    /**
+     * @description
+     * a string indicating the domain of the cookie (no default).
+     */
+    domain?: string;
+
+    /**
+     * @description
+     * a boolean or string indicating whether the cookie is a "same site" cookie (false by default). This can be set to 'strict',
+     * 'lax', 'none', or true (which maps to 'strict').
+     *
+     * @default false
+     */
+    sameSite?: 'strict' | 'lax' | 'none' | boolean;
+
+    /**
+     * @description
+     * a boolean indicating whether the cookie is only to be sent over HTTPS (false by default for HTTP, true by default for HTTPS).
+     */
+    secure?: boolean;
+
+    /**
+     * @description
+     * a boolean indicating whether the cookie is only to be sent over HTTPS (use this if you handle SSL not in your node process).
+     */
+    secureProxy?: boolean;
+
+    /**
+     * @description
+     * a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (true by default).
+     *
+     * @default true
+     */
+    httpOnly?: boolean;
+
+    /**
+     * @description
+     * a boolean indicating whether the cookie is to be signed (true by default). If this is true, another cookie of the same name with the .sig
+     * suffix appended will also be sent, with a 27-byte url-safe base64 SHA1 value representing the hash of cookie-name=cookie-value against the
+     * first Keygrip key. This signature key is used to detect tampering the next time a cookie is received.
+     */
+    signed?: boolean;
+
+    /**
+     * @description
+     * a boolean indicating whether to overwrite previously set cookies of the same name (true by default). If this is true, all cookies set during
+     * the same request with the same name (regardless of path or domain) are filtered out of the Set-Cookie header when setting this cookie.
+     */
+    overwrite?: boolean;
+}
+
 /**
  * @description
  * The AuthOptions define how authentication and authorization is managed.
@@ -172,6 +256,8 @@ export interface AuthOptions {
     tokenMethod?: 'cookie' | 'bearer';
     /**
      * @description
+     * **Deprecated** use `cookieConfig.secret` instead.
+     *
      * The secret used for signing the session cookies for authenticated users. Only applies when
      * tokenMethod is set to 'cookie'.
      *
@@ -180,8 +266,14 @@ export interface AuthOptions {
      * file not under source control, or from an environment variable, for example.
      *
      * @default 'session-secret'
+     * @deprecated use `cookieConfig.secret` instead
      */
     sessionSecret?: string;
+    /**
+     * @description
+     * Options related to the handling of cookies when using the 'cookie' tokenMethod.
+     */
+    cookieOptions?: CookieOptions;
     /**
      * @description
      * Sets the header property which will be used to send the auth token when using the 'bearer' method.

+ 0 - 1
packages/create/src/gather-user-responses.ts

@@ -190,7 +190,6 @@ async function generateSources(
         isSQLite: answers.dbType === 'sqlite',
         isSQLjs: answers.dbType === 'sqljs',
         requiresConnection: answers.dbType !== 'sqlite' && answers.dbType !== 'sqljs',
-        sessionSecret: Math.random().toString(36).substr(3),
     };
     const configTemplate = await fs.readFile(assetPath('vendure-config.hbs'), 'utf-8');
     const configSource = Handlebars.compile(configTemplate)(templateContext);

+ 1 - 2
packages/create/templates/vendure-config.hbs

@@ -36,7 +36,7 @@ const path = require('path');
         },// turn this off for production
         adminApiDebug: true, // turn this off for production
         shopApiPath: 'shop-api',
-        shopApiPlayground: { 
+        shopApiPlayground: {
             settings: {
                 'request.credentials': 'include',
             }{{#if isTs}} as any{{/if}},
@@ -44,7 +44,6 @@ const path = require('path');
         shopApiDebug: true,// turn this off for production
     },
     authOptions: {
-        sessionSecret: '{{ sessionSecret }}',
         superadminCredentials: {
             identifier: '{{ superadminIdentifier }}',
             password: '{{ superadminPassword }}',