Skip to content

Evaluate Account Linking interface #477

@bgins

Description

@bgins

We are evaluating the Webnative account linking interface and seeking feedback from developers.

Existing interface

Account linking in Webnative creates event emitters that listen for account linking events.

An accountProducer listens for a PIN from an accountConsumer and delegates the account when a user verifies the PINs match on both devices.

// The producer should already have an active session
const producer = await program.auth.accountProducer(program.session.username)

// The producer receives a challenge PIN from the consumer
producer.on("challenge", challenge => {
  // Either show `challenge.pin` or have the user input a PIN and check if they're equal.
  if (userInput === challenge.pin) challenge.confirmPin()
  else challenge.rejectPin()
})

// The producer reports whether a user approved or rejected
producer.on("link", ({ approved }) => {
  if (approved) console.log("Linked device successfully")
})

The accountConsumer listens for similar events:

// The consumer should not have an active session
const consumer = await program.auth.accountConsumer(username)

// The consumer generates a PIN and sends it to the producer
consumer.on("challenge", ({ pin }) => {
  // Display the PIN
  showPinOnUI(pin)
})

// The consumer receives an approval or rejection message from the producer
consumer.on("link", async ({ approved, username }) => {
  if (approved) {
    console.log(`Successfully authenticated as ${username}`)
    session = await program.auth.session()
  }
})

Alternative interface

An alternative interface could move the account linking to program.accountLinking and change the way it works.

A device with an existing session calls program.accountLinking.listen and listens for a PIN from a device that would like to be linked. It delegates the account when a user verifies the PINs match on both devices.

// On a device with an active session
program.accountLinking.listen()

// This device receives a PIN from the device that would like to be linked
program.accountLinking.on("challenge", (pin) => {
  // Either show `challenge.pin` or have the user input a PIN and check if they're equal.
  if (userInput === pin) program.accountLinking.confirmPin()
})

// Report whether the user approved or rejected
program.accountLinking.on("link", ({ approved }) => {
  if (approved) console.log("Linked device successfully")
})

A device that would like to be linked calls program.accountLinking.link and listens for similar messages.

// On a device without a session
program.accountLinking.link(username)

// This device generates a PIN and sends it to the device with an active session
program.accountLinking.on("challenge", (pin) => {
  // Display the PIN
  showPinInUI(pin)
})

// Handle an approval or rejection message from the device with an active session
program.accountLinking.on("link", ({ approved, username }) => {
  if (approved) {
    console.log(`Successfully authenticated as ${username}`)
    session = await program.auth.session()
  }
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions