Issuer label on QR code for 2FA not showing correct value

974 Views Asked by At

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)

[email protected] (<-- 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/[email protected]?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 "[email protected]". It seems it takes the first part of the email domain as the issuer. The result in Microsoft Authenticator app looks like this:

fakemail

[email protected]

But when I scan this exact same code in Google Authenticator app, it shows me (on one line):

Test Company ([email protected])

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

[email protected]

But in Google authenticator app, it shows in one line with the semi colon literally in there:

Test Company:[email protected]

What is the correct approach to have every single authenticator app in the exact same format?

1

There are 1 best solutions below

0
On BEST ANSWER

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' })