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

Add ability to auto-generate a random/unique value for Private access shared passwords #11537

Open
lb- opened this issue Jan 26, 2024 · 2 comments
Labels

Comments

@lb-
Copy link
Member

lb- commented Jan 26, 2024

Is your proposal related to a problem?

This is part of a set of improvements to help improve the way that the Private access (shared password method) works. See #10588

We want to make it easier for users to choose more secure values for this shared password, making it harder to guess and also gain access to easily with over the shoulder viewing of editors.

Describe the solution you'd like

Add the ability to generate a randomized string and also copy the value to the clipboard easily. Example screenshot below.

Mock (example) screenshot

This would involve;

  1. Enhancing client/src/controllers/ActionController.ts (ActionController) with the ability to create a random value.
  2. Enhancing ActionController to support it's actions targeting a specific element with a custom selector value.
  3. Adopting the ClipboardController for this field to support easy copy to clipboard behaviour. You can see how this is used in Feature/3683 url generator add copy button #11317 & Image URL generator is confusing for end users #3683 & the code snippet below.

<div class="w-relative" data-controller="w-clipboard w-clone" data-w-clone-auto-clear-value="5_000" data-action="w-clipboard:copy->w-clone#clear w-clipboard:copied->w-clone#add w-clipboard:error->w-clone#add">
<label class="w-sr-only" for="result-url">{% trans "Image URL" %}</label>
<textarea class="w-image-url-generator__url" id="result-url" rows="1" name="result-url" data-controller="w-action" data-action="focus->w-action#select" data-w-clipboard-target="value">
</textarea>
<button type="button" class="button button-secondary w-absolute w-top-3.5 w-right-3 w-bottom-auto w-left-auto" data-action="w-clipboard#copy" aria-describedby="clipboard-tooltip">
{% trans "Copy URL" %}
</button>
<div class="clipboard-tooltip" data-w-clone-target="container" id="clipboard-tooltip" aria-atomic="true" aria-live="polite"></div>
<template data-w-clone-target="template" data-type="success">
<span class="w-text-grey-50 w-absolute w-right-2 w-bg-positive-100 w-p-2 w-rounded-sm">{% trans 'Copied to clipboard' %}</span>
</template>
<template data-w-clone-target="template" data-type="error">
<span class="w-text-grey-50 w-absolute w-right-2 w-bg-critical-100 w-p-2 w-rounded-sm">{% trans 'Copying to clipboard failed' %}</span>
</template>
</div>


Important: It may make more sense to add this behaviour to the SlugController and rename that controller to something like CleanController (for cleaning/modifying field input values). Generally the change will be the same, have a read and provide thoughts in the comments.

ActionController - adding a new value

This controller is a bit of a toolkit controller, it let's us perform some kind of simple action on a button or input with Stimulus easily.

We will want to abstract the ability to get the most suitable target element. Read up on Stimulus values and actions if you are not sure what's happening here.

  static values = {
    target: { type: String, default: '' }, // add this
  };

  // add this method
  getTarget(event) {
    const { target = '' } = { ...event.detail, ...event.params };
    return (document.querySelector(target) || this.element) as HTMLElement;
  }

From there, we should really update all other methods to use this. e.g.

  click() {
    this.element.click();
  }
// would be replaced with.
  click(event) {
    this.getTarget(event).click();
  }

The other methods will be a bit more complex but not too much more.

ActionController - Add a unique method.

This would be very similar to reset on the ActionController but use a way to generate a set of unique values and output them as a string.

We would want to dispatch a change event also.

  unique(event) {
    const count = 5
    const array = new Uint32Array(5);
    // get the count from params/detail if possible.
    const newValue = [...window.crypto.getRandomValues(array)].map(val => val.toString(36)).join('-');
    // update the this.getTarget().value to the new value
  }

Describe alternatives you've considered

Multiple discussions have been had on #10588

Additional context

Working on this

  • Anyone can contribute to this if they have experience with Stimulus and TypeScript or are willing to learn.
  • PR must come with unit tests for all added Stimulus behaviour and also Python unit tests to check the basic addition of the HTML data attributes.
  • View our contributing guidelines, add a comment to the issue once you’re ready to start.
@RealOrangeOne
Copy link
Member

If we're going to include a password generator, we should make sure it works and is secure. window.crypto tends to only work in secure contexts (eg HTTPS and localhost), which might be an issue for some. Also, it would need to interact with Django's password validator framework, which is going to be quite complex.

Alternatively, we could link out to a password generator: https://bitwarden.com/password-generator/, at least in the first instance.

Or, final option, we do "Leave blank to generate a secure password", and defer the generation to the backend instead.

@lb-
Copy link
Member Author

lb- commented Jan 29, 2024

We could make a server side call if needed.

However I suggested the getRandomValues intentionally as it doesn't require secure context.

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues

As for the interaction with the password validation, I think we would just have to disable the generator if that feature is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants