I am using speakeasy library and qrcode library, to generate an otpauth URL and then transforming it into a QR code, so this can be scanned by an authenticator app for 2FA on my website.
I want the authenticator apps to show my website in the following format:
Test Company (<-- the name of my website)
test@fakemail.com (<-- the email of the user)
My code to generate the url is:
let url = speakeasy.otpauthURL({ secret: secret.base32, label: userEmail, issuer: 'Test Company', encoding: 'base32' })
This generates a URL like so:
otpauth://totp/test@fakemail.com?secret=ENTEWOKSHQRXQ4CYGBREYWDVFRTGYVRXNF2FWSBRKE7SUOJZGY4Q&issuer=Test%20Company
And then I transform it to a QR code like so:
let qrImageUrl = await qrcode.toDataURL(url)
I now try to set up 2FA with my user with email address "test@fakemail.com". It seems it takes the first part of the email domain as the issuer. The result in Microsoft Authenticator app looks like this:
fakemail
test@fakemail.com
But when I scan this exact same code in Google Authenticator app, it shows me (on one line):
Test Company (test@fakemail.com)
When changing the code to contain a colon like so:
let url = speakeasy.otpauthURL({ secret: secret.ascii, label: `Test Company:${userEmail}` })
In microsoft authenticator app it will now show perfectly like so:
Test Company
test@fakemail.com
But in Google authenticator app, it shows in one line with the semi colon literally in there:
Test Company:test@fakemail.com
What is the correct approach to have every single authenticator app in the exact same format?
Try pass all the possibilities combined into the same request. Normally the application itself will use the most applicable variables and will show accordingly in the specific app.
let url = speakeasy.otpauthURL({ secret: secret.base32, label: `Test Company:${userEmail}`, issuer: 'Test Company', encoding: 'base32' })