Merge pull request #384 from nodemailer/webauthn

Updated defaults for webauthn
This commit is contained in:
Andris Reinman 2022-03-07 10:33:09 +02:00 committed by GitHub
commit db05cd562c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 17 deletions

View file

@ -25,9 +25,12 @@ processes=1
#cipher="aes192" # only for decrypting legacy values (if there are any)
[webauthn]
rpId="example.com" # origin domain
rpName="WildDuck Email Server"
challengeSize=64
rpId = "example.com" # origin domain
rpName = "WildDuck Email Server"
challengeSize = 64
attestation = "none"
authenticatorUserVerification = "discouraged"
[attachments]
# @include "attachments.toml"

View file

@ -241,6 +241,11 @@ module.exports = (db, server, userHandler) => {
const schema = Joi.object().keys({
user: Joi.string().hex().lowercase().length(24).required(),
origin: Joi.string().empty('').uri().required(),
authenticatorAttachment: Joi.string()
.valid('platform', 'cross-platform')
.example('cross-platform')
.default('cross-platform')
.description('Indicates whether authenticators should be part of the OS ("platform"), or can be roaming authenticators ("cross-platform")'),
sess: sessSchema,
ip: sessIPSchema
});

View file

@ -220,7 +220,7 @@ module.exports = (db, server, userHandler, settingsHandler) => {
address: userData.address,
tags: userData.tags || [],
targets: userData.targets && userData.targets.map(t => t.value),
enabled2fa: Array.isArray(userData.enabled2fa) ? userData.enabled2fa : [].concat(userData.enabled2fa ? 'totp' : []),
enabled2fa: tools.getEnabled2fa(userData.enabled2fa),
autoreply: !!userData.autoreply,
encryptMessages: !!userData.encryptMessages,
encryptForwarded: !!userData.encryptForwarded,
@ -771,7 +771,7 @@ module.exports = (db, server, userHandler, settingsHandler) => {
language: userData.language,
retention: userData.retention || false,
enabled2fa: Array.isArray(userData.enabled2fa) ? userData.enabled2fa : [].concat(userData.enabled2fa ? 'totp' : []),
enabled2fa: tools.getEnabled2fa(userData.enabled2fa),
autoreply: !!userData.autoreply,
encryptMessages: userData.encryptMessages,

View file

@ -557,11 +557,13 @@ function formatFingerprint(fingerprint) {
function getEnabled2fa(enabled2fa) {
let list = Array.isArray(enabled2fa) ? enabled2fa : [].concat(enabled2fa ? 'totp' : []);
if (list.includes('u2f')) {
let listSet = new Set(list);
listSet.delete('u2f'); // not supported anymore
list = Array.from(listSet);
}
return list;
}

View file

@ -2398,8 +2398,6 @@ class UserHandler {
);
const registrationOptions = await f2l.attestationOptions();
delete registrationOptions.attestation;
registrationOptions.challenge = Buffer.from(registrationOptions.challenge).toString('hex');
registrationOptions.user = {
id: userData._id.toString(),
@ -2408,7 +2406,6 @@ class UserHandler {
};
registrationOptions.authenticatorSelection = Object.assign(registrationOptions.authenticatorSelection || {}, {
userVerification: 'discouraged',
authenticatorAttachment: data.authenticatorAttachment
});
@ -2607,20 +2604,28 @@ class UserHandler {
throw err;
}
const f2l = new Fido2Lib(Object.assign({}, config.webauthn));
const f2l = new Fido2Lib(
Object.assign(
{
authenticatorAttachment: data.authenticatorAttachment
},
config.webauthn
)
);
const authenticationOptions = await f2l.assertionOptions();
authenticationOptions.challenge = Buffer.from(authenticationOptions.challenge).toString('hex');
authenticationOptions.authenticatorSelection = Object.assign(authenticationOptions.authenticatorSelection || {}, {
userVerification: 'discouraged'
});
authenticationOptions.authenticatorSelection = Object.assign(authenticationOptions.authenticatorSelection || {}, {});
authenticationOptions.allowCredentials = userData.webauthn.credentials.map(credentialData => ({
rawId: credentialData.rawId.toString('hex'),
type: credentialData.type,
transports: credentialData.authenticatorAttachment === 'platform' ? ['internal'] : ['usb', 'nfc', 'ble']
}));
authenticationOptions.allowCredentials = userData.webauthn.credentials
.filter(credentialData => credentialData.authenticatorAttachment === data.authenticatorAttachment)
.map(credentialData => ({
rawId: credentialData.rawId.toString('hex'),
type: credentialData.type,
transports: credentialData.authenticatorAttachment === 'platform' ? ['internal'] : ['usb', 'nfc', 'ble']
}));
// store chalenge
let challengeKey = `challenge:${userData._id.toString()}:auth:${authenticationOptions.challenge}`;