Giter Club home page Giter Club logo

Comments (17)

aronmal avatar aronmal commented on September 28, 2024 1

Ok, I am currently working on it. I got a big confusion out of my way, the migration format uses Percent-encoding. After that, it is decodeable with protobuf.

Question to you @Bubka, should the conversion from otpauth-migration://offline?data=... to otpauth://totp/... format happen client or server side?

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024 1

https://github.com/aronmal/2FAuth/commit/b61cf94f8080e80f1ea599fa83c6ddb02ff9f4bf in case you need the .proto file or want to test it.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024 1

Sorry it's a very busy week. I've prioritize the proxy Auth issues since Monday, I hope I could review this on Thursday.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024 1

Sure, but it's not that simple.

2Fauth uses 2 different QR decoders, one for the live scan, run by Vue, and one for uploaded QRs, run by the back-end.

Moreover, forcing the user to import a single account whereas Google Authenticator allows to export the whole accounts would result in a bad UX. It is also necessary to create a dedicated UI to handle specific messages during the import process, especially in case of treatment error.

I'm working on it.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024 1

FYI, I committed some changes to the dev branch this afternoon, Google Authenticator export is now supported, just scan/upload the QR code provided by G-Auth to fire the import feature.

The 2fauth/2fauth:dev docker image is up-to-date if you want to give it a try.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024

FYI there is a discussion about this feature here: #27

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

Great to see it is already in Mind. But the last comments were made in Aug 2021. I would love to try to contribute at this point maybe, but please brief me real quick, the QR code is being recognized in a picture, the payload is read, in this case protobuf need to be decoded and then the new TOTP is being saved. Could you give me some sort of flow chart what library/methods you use for what step and if they're client or server side. Then I would give myself a try on this.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024

Question to you @Bubka, should the conversion from otpauth-migration://offline?data=... to otpauth://totp/... format happen client or server side?

Is this just a string conversion or is there some logic to implement?

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

Is this just a string conversion or is there some logic to implement?

There is quite some logic with bit shifting and stuff. I am orienting on protobuf-decoder and making progress understanding it. But because he already wrote some of the js conversion, my guess would be to take his approach and adjust it for the otpauth-migration://offline?data=... to otpauth://totp/... format conversion, because why reinvent the wheel. So, my guess would be either to create a npm package to convert the format (which I would love to, but have never done before), or just implement it in your vue frontend at least for now.

What do you think @Bubka ?

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

I am blind, there is an official package. I will make a sample script, then you can implement it at the right place in your vue fronted.

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

The package is not needed. The .proto file is being compiled to a _pb.js file which than can be used to deserialize the base64 string.

The working code looks like this:

carbon

const Base32 = require('hi-base32'); // Install with 'npm install hi-base32'
const otpauth_migration = require('./otpauth-migration_pb'); // Is compiled with the command (works on linux) 'protoc --js_out=import_style=commonjs,binary:. ./otpauth-migration.proto' and the .proto file from 'https://github.com/digitalduke/otpauth-migration-decoder/blob/master/src/otpauth-migration.proto'

const otpauth_migration_format = 'otpauth-migration://offline?data='; // This is what needs to be replaced from the input with an empty string
const Algorithm = {
    1: 'SHA1',
    2: 'SHA256',
    3: 'SHA512',
    4: 'MD5',
};
const DigitCount = {
    1: '6',
    2: '8',
};
const OtpType = {
    1: 'hotp',
    2: 'totp',
};

const input = "otpauth-migration://offline?data=CjEKCkhlbGxvId6tvu8SGEV4YW1wbGU6YWxpY2VAZ29vZ2xlLmNvbRoHRXhhbXBsZTAC"; // The Input. Obviously.

const uriDecoded = decodeURIComponent(input.replace(otpauth_migration_format, '')); // Replacing function to get only the data and use decodeURIComponent() to decode Percent-encoding. We are left with an base64 string.
const protobufDecoded = otpauth_migration.Payload.deserializeBinary(uriDecoded).array[0]; // Here happens the real magic, the base64 string to an array of OTPs.
const otpDecode = (otpArray) => otpArray.map(otp => { // Map the OTPs array
    const otp_type = OtpType[otp[5] || 1],
        otp_name = otp[1],
        otpParams = {
            Algorithm: Algorithm[otp[3] || 1],
            DigitCount: DigitCount[otp[4] || 1],
            Issuer: otp[2],
            Period: 30,
            Secret: Base32.encode(Buffer.from(otp[0]))
        },
        otp_params = [
            `algorithm=${otpParams.Algorithm}`,
            `digits=${otpParams.DigitCount}`,
            `issuer=${otpParams.Issuer}`,
            `period=${otpParams.Period}`,
            `secret=${otpParams.Secret}`
        ].join('&'),
        otpauth = `otpauth://${otp_type}/${otp_name}?${otp_params}`; //Put together the otpauth link
    return otpauth;
})

console.log(otpDecode(protobufDecoded)); // Évoilà, there we have our exportet/transfered Google Authenticator OTPs
// Expected output: ['otpauth://totp/Example:[email protected]?algorithm=SHA1&digits=6&issuer=Example&period=30&secret=JBSWY3DPEHPK3PXP']

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

@Bubka 👀

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

In this file you have a regex. I don't know much about php, so no plan how to disable this check, but because I'm familiar with typescript and react I found where (here and here) to implement the conversion in vue. So my request would be to not check with the regex, but just parse the decoded QR Code and then do a check in vue if it matches the regex, otherwise 'optauth-migration' regex, in that case convert it or then throw an error.

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

And another question, you can export multiple accounts at the same time. You have an array,, but I would just hard code it to take the first in the array.

from 2fauth.

Bubka avatar Bubka commented on September 28, 2024

Hi @aronmal

I've been reading and testing around protobuf and an import feature past days. And at the end I think that the protobuf decoding has to be done by the back-end.

The main reason is that 2FAuth has all its business logic implemented server-side, and exposes an API through the back-end capabilities. If the protobuf decoding is done by Vue then the API won't be able to provide an endpoint to import GoogleAuth data.

Thanks to your previous contributions I was able to implement the protobuf decoding with PHP 👍🏻

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

OK, my Idea was like:

const { data } = await this.form.upload('/api/v1/qrcode/decode', imgdata)

const otpauthRegex = /^otpauth:\/\/[h,t]otp\//i;
const decodedUri = otpauthRegex.test(data.data) ? data.data : otpmigrationDecode(data.data)

this.$router.push({ name: 'createAccount', params: { decodedUri } });

in the Start.vue and Create.vue. But when you can implement it in php it is also fine I guess.

from 2fauth.

aronmal avatar aronmal commented on September 28, 2024

I will give it a try when I find time for it. Nice job!

from 2fauth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.