+
+ /**
+ * Checks a supplied credential against supplied data.
+ * @param {AuthInfo} authData from database
+ * @param {String} credential plaintext
+ * @returns {Promise<Boolean>}
+ */
+ async _validateAuthDataCredential(authData, credential) {
+ const _scope = _fileScope('_validateAuthDataCredential');
+
+ if (!authData?.credential) {
+ this.logger.debug(_scope, 'failed, no authInfo');
+ return false;
+ }
+ if (authData.credential.startsWith('$argon2')
+ && this.authnEnabled.has('argon2')) {
+ return await this._isValidArgon2Identifier(authData, credential);
+ }
+ if (authData.credential.startsWith('$PAM$')
+ && this.authnEnabled.has('pam')) {
+ return await this._isValidPAMIdentifier(authData, credential);
+ }
+ if (authData.credential.startsWith('$plain$')
+ && this.authnEnabled.has('plain')) {
+ return this.constructor._isValidPlainIdentifier(authData, credential);
+ }
+ this.logger.error(_scope, 'failed, unknown or unsupported type of stored credential', { authData });
+ return false;
+ }
+
+
+ /**
+ * Check argon2.
+ * @param {AuthInfo} authData
+ * @param {String} credential
+ * @returns {Promise<Boolean>}
+ */
+ async _isValidArgon2Identifier(authData, credential) {
+ return await this.authn.argon2.verify(authData.credential, credential);
+ }
+
+
+ /**
+ * Check plaintext.
+ * @param {AuthInfo} authData
+ * @param {String} credential
+ * @returns {Promise<Boolean>}
+ */
+ static _isValidPlainIdentifier(authData, credential) {
+ return authData.credential.substring('$plain$'.length) === credential;