Lee
Lee

Reputation: 31060

Export gun auth credentials for login on different device/ in different session

Say I create a gun user like so:

let user = gun.user() 
user.create('Bob','password123',console.log) 
user.auth('Bob' ,'password123',console.log) 

I can see that I can export the key pair using user._.sea, but am unsure whether I need (/whether it's possible) to export the salt as well. Is it possible to access the act object of the create prototype?

What is a good way to export the private key / salt such that the user could save a string (say a jwk) and use to authenticate on a different device?

What functions could you use to import the key in another session?

Upvotes: 0

Views: 110

Answers (2)

user20067448
user20067448

Reputation: 21

tldr:

//this is a loged in instance of gun.user;
let pair = this.user._.sea;

I show it in a qr code, this code is not polished but not bad.

    /**
     * Show you private
     */
    function showPair() {
        let pair = this.user._.sea;
        let qr = bs.str2qr(pair)

        let w = bs.getGoodWidth();

        let img = qr.createImgTag()

        let html = ''
        html += qr.createSvgTag(undefined, 1, this.user.is.alias, "GUN AUTH PAIR")

        html += `<pre>${JSON.stringify(pair, null, 1)}</pre>`

        jsPanel.create({
            headerTitle: "GUN AUTH PAIR",
            headerToolbar: [
                "<input name='password' placeholder='password make it secure!'>",
                "<button name='recovery'>Freeze Recovery</button>"
            ],
            panelSize: {
                width: w,
                height: w + 20
            },
            content: html,
            callback: panel => {
                let s = panel.querySelector(`svg[role='img']`)
                s.setAttribute('width', '99%')
                s.setAttribute('height', null)

                let i = panel.querySelector(`input[name='password']`)
                let b = panel.querySelector(`button[name='recovery']`)
                b.addEventListener('click', e => {
                    let p = i.value;
                    if (p.length < 12) {
                        this.resNotify({success: false, msg: 'Make a good password its your only line of defence'});
                        return;
                    }

                    this.registerRecovery(p, (key, id) => {
                        bs.showQr(id);
                    })


                })

            }
        })
    }

https://bullchat.syon.ca/js/bs.js see example. at https://bullchat.syon.ca login then showPair

var bs = {
//get a qr to this host with param id
    id2qr: (id, param = 'id', s) => {
        return bs.str2qr(window.location.host + '?' + param + '=' + encodeURIComponent(id), s)
    },

    //make a string into a qr scaling up size until it works
    str2qr: (str, size = 10, setCorrection = ['H', 'Q', /*'M', 'L'*/]) => {
        // L : 1,
        //     M : 0,
        //     Q : 3,
        //     H : 2

        if (!Array.isArray(setCorrection)) setCorrection = [setCorrection];

        let correcti
        console.log(str, size)
        for (let s = size; s <= 40; s++) {
            for (l of setCorrection) {
                try {
                    let qr = qrcode(s, l);
                    qr.addData(str);
                    qr.make();
                    return qr;
                } catch (e) {
                    console.error('failed at  error correction: ', l, " size: ", s, ' e: ', e)
                }
            }
        }


        return qr.createImgTag();
        return bs.str2qr(window.location.host + '?' + param + '=' + encodeURIComponent(id))
    },

    /**
     * Requires qrcode.js see bullchat
     * @param id
     * @param title
     */
    showQr: (id, title = 'My QR') => {
        let qr = bs.id2qr(id)

        let w = bs.getGoodWidth();

        let img = qr.createImgTag()
        jsPanel.create({
            headerTitle: 'QR Code: ' + title,
            panelSize: {
                width: w,
                height: w + 20
            },
            content: qr.createSvgTag(undefined, 1, id, title),
            callback: panel => {
                let s = panel.querySelector(`svg[role='img']`)
                s.setAttribute('width', '99%')
                s.setAttribute('height', null)

            }
        })

    },

    showSvg: (id, title) => {
        let w = bs.getGoodWidth();

        let img = qr.createImgTag()
        jsPanel.create({
            headerTitle: 'QR Code: ' + title,
            panelSize: {
                width: w,
                height: w + 20
            },
            content: qr.createSvgTag(undefined, 1, id, title),
            callback: panel => {
                let s = panel.querySelector(`svg[role='img']`)
                s.setAttribute('width', '99%')
                s.setAttribute('height', null)

            }
        })
    },

    /**
     *
     * @param [aspect=8.5/11] = aspect ratio to target w/h ie 1920/1080 or 8.5/11
     * @param [thresh=500] -  max of 1/2 width or thresh used to find preferred width.
     * @param [pad=100] - how much to pad the edges by note 100 = 50 top 50 bottom
     * @param opts
     */
    getGoodPanelSize(aspect = 8.5 / 11, thresh, pad = 100, opts) {
        // opts = opts || {};
        // opts.aspect = opts.aspect || 8.5/11

        let w = document.body.clientWidth - pad;
        let h = document.body.clientHeight - pad;

        //the
        let t = thresh || Math.max(w / 2, 500)

        let gw = bs.getGoodWidth(t, pad)

        //if the good height is to tall user the panel height
        let ph = Math.min(h, gw * (1 / aspect));

        //then compute with based on height to maintain aspect
        let pw = Math.min(h, ph * aspect);

        return {width: pw, height: ph};


    },

    /**
     * Thresh or screen with whichever smaller
     * @param [thresh=500]
     * @returns {number}
     */
    getGoodWidth: (thresh = 500, pad = 50) => {

        let w = document.body.clientWidth - pad;

        // let thresh = 500
        if (w > thresh) w = thresh;

        return w;
        // let h = document.body.clientHeight;

    },
}

https://bullchat.syon.ca/js/lib/qrcode.js

Upvotes: 2

Lee
Lee

Reputation: 31060

To export:

Session 1:

let user = gun.user() 
user.create('Bob','password123',console.log) 
user.auth('Bob' ,'password123',console.log) 

JSON.stringify(user._.sea) // prompt user to export / "download"

To import:

Session 2:

let user = gun.user() 
let imported_JSON //Prompt user to import JSON as imported_JSON
let pair = JSON.parse(imported_JSON)
user.auth(pair,console.log) // user now authorised on session 2

Upvotes: 0

Related Questions