Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): optional account recovery #1546

Merged
merged 12 commits into from
Sep 16, 2024
Merged

feat(client): optional account recovery #1546

merged 12 commits into from
Sep 16, 2024

Conversation

fforbeck
Copy link
Member

@fforbeck fforbeck commented Sep 6, 2024

Issue storacha/project-tracking#124

Current Workflow (CLI)

w3cli Project

The space.create(name, options) function in space.js allows the user to pass the following options:

  • recovery: false (default)
  • caution: false (default)
  • customer: Email | false
  • account: string | false

If the account attribute is provided, the following steps are triggered:

  1. space.createdRecovery is called.
  2. Then, client.capabilities.access.delegate is executed.

This process occurs during space creation, not during provisioning.
Provisioning only happens when the customer attribute is provided in the options argument.


Issue (JS Client)

w3up Project

The client.createSpace(name) function in the w3up project currently does not accept any options, which means the recovery account must be created manually after space creation and provisioning. This introduces a risk of forgetting the manual step and potentially losing access to the space.


Expected Outcome

We propose a small modification to the client.createSpace(name) function to support optional parameters, allowing clients to pass an account directly, automating the recovery setup.

Solution:

  • Clients can now call client.createSpace(name, { account }) to include the account in the creation process.
  • This ensures that the recovery account is created immediately after the space is created, provisioned, and saved, eliminating the need for a manual step.

Benefits:

  • Backward Compatibility: The change does not break existing client implementations since the account parameter is optional, keeping calls like client.createSpace(name) intact.
  • Simplified Workflow: By simply passing the account when calling createSpace, the recovery account setup is handled automatically during space creation.
  • Flexibility: If needed in the future, the account attribute can be made required to enforce stricter recovery account management.

Signed-off-by: Felipe Forbeck <felipe.forbeck@gmail.com>
Copy link
Member

@hannahhoward hannahhoward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach is fine, except I have one nit around using an account object rather than an email.

Also we should submit a PR to github.com/storacha-network/docs to update the docs for the JS client.

packages/w3up-client/src/client.js Show resolved Hide resolved
@fforbeck
Copy link
Member Author

@hannahhoward

The last commit introduces a new test case to ensure that when Alice creates a space, her account is correctly set as the recovery account. The test verifies that Alice retains access to the space from another device by checking the space's accessibility.

In the client.js, I modified the createSpace function to provision and save the space before delegating access to the recovery account. This ensures that the necessary authorizations are in place for the delegation.

If that looks good to you I will update the documentation.

Copy link
Member

@hannahhoward hannahhoward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, this is obviously not ideal to have all this logic in creating a space, on the otherhand, with the chain of dependencies there's no way to seperate it. And it will make for a much shorter setup tutorial, which will be quite nice. We should definitely update docs for this.

Copy link
Member

@hannahhoward hannahhoward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alanshaw
Copy link
Member

@fforbeck how does this affect the space creation steps in the CLI?

Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great but please could you try to keep non essential changes to a minimum? There's a lot of code formatting change in here that makes it harder for me to review. Just submit a separate PR in the future for code formatting changes 🙏.

packages/w3up-client/src/client.js Outdated Show resolved Hide resolved
packages/w3up-client/src/client.js Outdated Show resolved Hide resolved
packages/w3up-client/src/client.js Show resolved Hide resolved
fforbeck and others added 2 commits September 13, 2024 09:13
Co-authored-by: Alan Shaw <alan.shaw@protocol.ai>
Co-authored-by: Alan Shaw <alan.shaw@protocol.ai>
@fforbeck
Copy link
Member Author

This is a great but please could you try to keep non essential changes to a minimum? There's a lot of code formatting change in here that makes it harder for me to review. Just submit a separate PR in the future for code formatting changes 🙏.

Yeah, my bad. I will revert these formatting changes to simplify this PR.

@fforbeck
Copy link
Member Author

@fforbeck how does this affect the space creation steps in the CLI?

The CLI should remain unaffected by this change because the account parameter is optional. The existing logic in the CLI already supports space creation without requiring an account, and it includes the necessary recovery logic (e.g., this line in the code).

In the future, we could create a separate PR to simplify the CLI code by leveraging the new version of the createSpace function. However, given the current implementation, there should be no impact on the CLI’s functionality.

@fforbeck
Copy link
Member Author

@alanshaw
I've applied the suggested changes and reverted the formatting stuff. I just had to do a minor tweak in the GH Action to be able to run it on the CI - which was failing.

@fforbeck fforbeck changed the title feat(client): optional email recovery feat(client): optional account recovery Sep 13, 2024
Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


```js
// wait for payment plan to be selected
while (true) {
const res = await account.plan.get()
if (res.ok) break
console.log('Waiting for payment plan to be selected...')
await new Promise(resolve => setTimeout(resolve, 1000))
await new Promise((resolve) => setTimeout(resolve, 1000))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be rad if this was a method of the client? Would you be up for adding something like that quickly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I will add that.

await new Promise((resolve) => setTimeout(resolve, 1000))
}
// Wait for a payment plan with a 1-second polling interval and 60-second timeout
await client.waitForPaymentPlan(account, 1000, 60000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 can we land as a separate PR? Apologies - I should have asked...

I think it might be better for this to be an instance method of AccountPlan rather than the top level? WDYT?

await account.plan.wait()

In the docs I think it's simplier to just use the defaults (i.e. don't specify the interval/timeout).

* @param {Account.Account} account - The account object to check the payment plan for.
* @param {number} [interval=1000] - The polling interval in milliseconds (default is 1000ms).
* @param {number} [timeout=180000] - The maximum time to wait in milliseconds before throwing a timeout error (default is 3 minutes).
* @returns {Promise<void>} - Resolves once a payment plan is selected within the timeout.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return the plan information when it is available.

* at a specified interval until a valid plan is selected or the timeout is reached.
*
* @param {Account.Account} account - The account object to check the payment plan for.
* @param {number} [interval=1000] - The polling interval in milliseconds (default is 1000ms).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd pass an options object with these two properties.

*
* @param {Account.Account} account - The account object to check the payment plan for.
* @param {number} [interval=1000] - The polling interval in milliseconds (default is 1000ms).
* @param {number} [timeout=180000] - The maximum time to wait in milliseconds before throwing a timeout error (default is 3 minutes).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to pass an AbortSignal instead so that if folks are using this in a UI they can have a cancel button. Another reason is that it could take longer than 3 minutes, considering you have to log into your email, click the link, add credit card details etc.

message: 'Timeout: Payment plan selection took too long.',
})
},
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@fforbeck fforbeck merged commit ea02adb into main Sep 16, 2024
7 checks passed
@fforbeck fforbeck deleted the add-opt-email-recovery branch September 16, 2024 12:52
fforbeck pushed a commit that referenced this pull request Sep 16, 2024
🤖 I have created a release *beep* *boop*
---


##
[16.1.0](w3up-client-v16.0.0...w3up-client-v16.1.0)
(2024-09-16)


### Features

* **client:** optional account recovery
([#1546](#1546))
([ea02adb](ea02adb))
* wait for plan selection
([#1547](#1547))
([7fdee77](7fdee77))


### Other Changes

* Add `pnpm dev` to watch-build all packages
([#1533](#1533))
([07970ef](07970ef))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
fforbeck added a commit to storacha/docs that referenced this pull request Sep 16, 2024
### Changes
The `createSpace` function in `client.js` has been enhanced to
streamline the space creation process. The new workflow now
automatically handles the following steps:
- Provisions the space.
- Saves the space.
- Creates a recovery account.
- Delegates access to the recovery account.

This update removes the need for manual steps, ensuring the recovery
account is set up as part of the space creation process.

> **Note:** This PR should only be merged after
[storacha/w3up#1546](storacha/w3up#1546) has
been merged and released.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants