handle undefined credential more gracefully
[squeep-authentication-module] / lib / authenticator.js
index 1cff2108f309e2ac51245070281e0ec346f6168c..4449a94b700889f5c2196b77c91872ed0b52d26d 100644 (file)
@@ -20,6 +20,7 @@ class Authenticator {
    * @param {Boolean} options.authenticator.secureAuthOnly
    * @param {String[]} options.authenticator.forbiddenPAMIdentifiers
    * @param {String[]} options.authenticator.authnEnabled
+   * @param {Number=} options.authenticator.inactiveSessionLifespanSeconds
    * @param {String[]=} options.authenticator.loginBlurb
    * @param {String[]=} options.authenticator.indieAuthBlurb
    * @param {String[]=} options.authenticator.userBlurb
@@ -51,6 +52,8 @@ class Authenticator {
     }
 
     this.mysteryBox = new MysteryBox(logger, options);
+
+    this.cookieLifespan = options.authenticator.inactiveSessionLifespanSeconds || 60 * 60 * 24 * 32;
   }
 
 
@@ -63,10 +66,14 @@ class Authenticator {
    */
   async isValidIdentifierCredential(identifier, credential, ctx) {
     const _scope = _fileScope('isValidIdentifierCredential');
-    this.logger.debug(_scope, 'called', { identifier, credential: '*'.repeat(credential.length), ctx });
+    this.logger.debug(_scope, 'called', { identifier, credential: '*'.repeat((credential || '').length), ctx });
 
     let isValid = false;
 
+    if (typeof credential === 'undefined') {
+      return isValid;
+    }
+
     await this.db.context(async (dbCtx) => {
       const authData = await this.db.authenticationGet(dbCtx, identifier);
       if (!authData) {
@@ -259,6 +266,18 @@ class Authenticator {
     &&  (ctx.session.authenticatedIdentifier
          || (profilesAllowed && ctx.session.authenticatedProfile))) {
       this.logger.debug(_scope, 'valid session cookie', { ctx });
+      // Refresh timeout on valid session.
+      const cookieParts = [
+        sessionCookie,
+        'HttpOnly',
+        `Max-Age=${this.cookieLifespan}`,
+        'SameSite=Lax',
+        `Path=${this.options.dingus.proxyPrefix}/`,
+      ];
+      if (this.options.authenticator.secureAuthOnly) {
+        cookieParts.push('Secure');
+      }
+      res.setHeader(Enum.Header.SetCookie, cookieParts.join('; '));
       return true;
     }
 
@@ -268,6 +287,7 @@ class Authenticator {
         `${Enum.SessionCookie}=""`,
         'HttpOnly',
         'Max-Age=0',
+        'SameSite=Lax',
         `Path=${this.options.dingus.proxyPrefix}/`,
       ];
       if (this.options.authenticator.secureAuthOnly) {
@@ -371,4 +391,4 @@ class Authenticator {
 
 }
 
-module.exports = Authenticator;
\ No newline at end of file
+module.exports = Authenticator;