Skip to content

Commit

Permalink
feat: add cancel create account (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
hugomrdias authored Nov 1, 2022
1 parent cddf7b9 commit feec113
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
52 changes: 34 additions & 18 deletions packages/access/src/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as Account from './capabilities/account.js'
import * as Voucher from './capabilities/voucher.js'
import { any as Any } from './capabilities/any.js'
import { stringToDelegation } from './encoding.js'
import { Websocket } from './utils/ws.js'
import { Websocket, AbortError } from './utils/ws.js'

/**
* @template T
Expand Down Expand Up @@ -129,8 +129,10 @@ export class Agent {

/**
* @param {string} email
* @param {object} [opts]
* @param {AbortSignal} [opts.signal]
*/
async createAccount(email) {
async createAccount(email, opts) {
const account = await this.store.createAccount()
const service = await this.service()
const delegationToAgent = await Any.delegate({
Expand Down Expand Up @@ -158,7 +160,7 @@ export class Agent {
throw new Error('Account creation failed', { cause: inv.error })
}

const voucherRedeem = await this.#waitForVoucherRedeem()
const voucherRedeem = await this.#waitForVoucherRedeem(opts)
// TODO save this delegation so we can revoke later
const delegationToService = await Any.delegate({
issuer: account,
Expand Down Expand Up @@ -189,29 +191,43 @@ export class Agent {
this.store.save(this.data)
}

async #waitForVoucherRedeem() {
/**
*
* @param {object} [opts]
* @param {AbortSignal} [opts.signal]
*/
async #waitForVoucherRedeem(opts) {
const ws = new Websocket(this.url, 'validate-ws')
await ws.open()

ws.send({
did: this.did(),
})
const msg = await ws.awaitMsg()
if (msg.type === 'timeout') {
await ws.close()
throw new Error('Email validation timed out.')
}

if (msg.type === 'delegation') {
const delegation = await stringToDelegation(
/** @type {import('./types').EncodedDelegation<[import('./types').VoucherRedeem]>} */ (
msg.delegation
try {
const msg = await ws.awaitMsg(opts)

if (msg.type === 'timeout') {
await ws.close()
throw new Error('Email validation timed out.')
}

if (msg.type === 'delegation') {
const delegation = await stringToDelegation(
/** @type {import('./types').EncodedDelegation<[import('./types').VoucherRedeem]>} */ (
msg.delegation
)
)
)
ws.close()
return delegation
ws.close()
return delegation
}
} catch (error) {
if (error instanceof AbortError) {
await ws.close()
throw new TypeError('Failed to get voucher/redeem', { cause: error })
}
}

throw new Error('Failed to get voucher/redeem')
throw new TypeError('Failed to get voucher/redeem')
}

/**
Expand Down
31 changes: 30 additions & 1 deletion packages/access/src/utils/ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,23 @@ export class Websocket {
}
}

awaitMsg() {
/**
*
* @param {object} [opts]
* @param {AbortSignal} [opts.signal]
*/
awaitMsg(opts) {
return new Promise((resolve, reject) => {
if (opts?.signal) {
opts.signal.addEventListener('abort', () => {
this.onMessage = undefined
reject(
new AbortError('Await message cancelled.', {
cause: opts.signal?.reason,
})
)
})
}
this.onMessage = (/** @type {{ type: string; }} */ msg) => {
try {
this.onMessage = undefined
Expand All @@ -194,3 +209,17 @@ export class Websocket {
})
}
}

export class AbortError extends Error {
/**
* @param {string} message
* @param {ErrorOptions} [opts]
*/
constructor(message, opts) {
super(message, opts)
this.name = 'AbortError'
this.message = message
this.code = AbortError.code
}
}
AbortError.code = 'ERR_AWAIT_MSG_CANCEL'

0 comments on commit feec113

Please sign in to comment.