allow config of session cookie sameSite value
[squeep-authentication-module] / lib / authenticator.js
index 3df0b9db17ccdf763ce13b6340e912b0d6545266..86b95d6d035e92284756476a1baae491908a5f18 100644 (file)
@@ -53,15 +53,16 @@ class Authenticator {
    * @param {object} options options
    * @param {string | string[]} options.encryptionSecret encryption secret
    * @param {object} options.authenticator authenticator options
-   * @param {boolean} options.authenticator.secureAuthOnly disable auth over non-https
-   * @param {string[]} options.authenticator.forbiddenPAMIdentifiers reject these identifiers for PAM auth
-   * @param {string[]} options.authenticator.authnEnabled in order of preference for storing new credentials
+   * @param {boolean=} options.authenticator.secureAuthOnly disable auth over non-https
+   * @param {string=} options.authenticator.sessionCookieSameSite sameSite setting for session cookie, default Lax
+   * @param {string[]=} options.authenticator.forbiddenPAMIdentifiers reject these identifiers for PAM auth
+   * @param {string[]=} options.authenticator.authnEnabled in order of preference for storing new credentials
    * @param {number=} options.authenticator.inactiveSessionLifespanSeconds session timeout
    * @param {string[]=} options.authenticator.loginBlurb text for login page
    * @param {string[]=} options.authenticator.indieAuthBlurb text for indieauth login section
    * @param {string[]=} options.authenticator.userBlurb text for local user login section
    * @param {string[]=} options.authenticator.otpBlurb text for otp entry
-   * @param {string=} options.dingus dingus options
+   * @param {object=} options.dingus dingus options
    * @param {string=} options.dingus.proxyPrefix base url prefix
    */
   constructor(logger, db, options) {
@@ -70,8 +71,13 @@ class Authenticator {
     this.options = options;
     this.basicRealm = options.authenticator.basicRealm || packageName;
     this.secureAuthOnly = options.authenticator.secureAuthOnly ?? true;
+    this.sameSite = options.authenticator.sessionCookieSameSite || 'Lax';
     this.proxyPrefix = options.dingus?.proxyPrefix ?? '';
 
+    if (!['None', 'Lax', 'Strict'].includes(this.sameSite)) {
+      throw new RangeError(`invalid sameSite value "${this.sameSite}"`);
+    }
+
     // First construct map of all available code-supported auth mechanisms.
     this.authn = {
       indieAuth: {},
@@ -476,7 +482,7 @@ class Authenticator {
       common.addCookie(res, Enum.SessionCookie, ctx.cookie[Enum.SessionCookie], {
         httpOnly: true,
         maxAge: this.cookieLifespan,
-        sameSite: 'Lax',
+        sameSite: this.sameSite,
         path: `${this.proxyPrefix}/`,
         secure: this.secureAuthOnly,
       });
@@ -488,7 +494,7 @@ class Authenticator {
       common.addCookie(res, Enum.SessionCookie, '""', {
         httpOnly: true,
         maxAge: 0,
-        sameSite: 'Lax',
+        sameSite: this.sameSite,
         path: `${this.proxyPrefix}/`,
         secure: this.secureAuthOnly,
       });