decidim-friendly_signup 0.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +33 -18
- data/app/controllers/concerns/decidim/friendly_signup/needs_header_snippets.rb +2 -5
- data/app/controllers/decidim/friendly_signup/application_controller.rb +8 -0
- data/app/controllers/decidim/friendly_signup/validator_controller.rb +18 -0
- data/app/packs/entrypoints/decidim_friendly_signup.js +2 -1
- data/app/packs/src/decidim/friendly_signup/lib/instant_validator.js +95 -0
- data/app/packs/src/decidim/friendly_signup/{password_toggler.js → lib/password_toggler.js} +0 -0
- data/app/packs/src/decidim/friendly_signup/{password_helper.js → setup_password.js} +1 -1
- data/app/packs/src/decidim/friendly_signup/setup_validations.js +7 -0
- data/app/views/decidim/devise/registrations/new.html.erb +5 -5
- data/app/views/decidim/friendly_signup/shared/_password_fields.html.erb +1 -1
- data/lib/decidim/friendly_signup/engine.rb +4 -0
- data/lib/decidim/friendly_signup/user_attribute_validator.rb +49 -0
- data/lib/decidim/friendly_signup/version.rb +1 -1
- data/lib/decidim/friendly_signup.rb +15 -0
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c631ec440674f278ea3a0f3369435831014443e36f2f4247d1a87d914e7e66c8
|
4
|
+
data.tar.gz: cf5ca968cfe4459a63471e02ff36dd38f28cfb042c3146e175c3766dab4a6571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdd1a58fad3b2b40cb5f73497c3ca408a621afce743073b40c9fee720a4e9050e0d5a8f3b495e5024b6e807ce7fe8c61859e264259fd3ccec30424d025114bb3
|
7
|
+
data.tar.gz: b0437d886f9018aaed1a3f405f52032d77c8c01ec7f1f40bb8a61b708138f1eeedbacb424ab394d26048c7bb643d14b3579ddce4954cd5c2af521fea6ffc8f38
|
data/README.md
CHANGED
@@ -1,21 +1,25 @@
|
|
1
1
|
# Decidim::FriendlySignup
|
2
2
|
|
3
|
+
[![[CI] Lint](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/lint.yml/badge.svg)](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/lint.yml)
|
3
4
|
[![[CI] Test](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/test.yml/badge.svg)](https://github.com/OpenSourcePolitics/decidim-module-friendly_signup/actions/workflows/test.yml)
|
4
5
|
[](https://codeclimate.com/github/OpenSourcePolitics/decidim-module-friendly_signup/maintainability)
|
5
6
|
[](https://codecov.io/gh/OpenSourcePolitics/decidim-module-friendly_signup)
|
7
|
+
[](https://badge.fury.io/rb/decidim-friendly_signup)
|
8
|
+
|
6
9
|
---
|
7
|
-
|
10
|
+
|
11
|
+
A more user friendly approach for the user registration process in [Decidim](https://github.com/decidim/decidim).
|
8
12
|
|
9
13
|
## Usage
|
10
14
|
|
11
15
|
This module simply substitutes some pages to ease up the registration process in Decidim.
|
12
16
|
|
13
|
-
Features:
|
17
|
+
### Features:
|
14
18
|
|
15
19
|
- [x] Simplify the password field and add a button with a "show password". 
|
16
20
|
|
17
21
|
- [ ] Remove the nickname field from the registration process and automatically create one on registering
|
18
|
-
- [
|
22
|
+
- [x] Instant validate parameters when registering without having to send it for backend validation. 
|
19
23
|
- [ ] Use checkout codes to validate the email instead of a link
|
20
24
|
|
21
25
|
## Installation
|
@@ -38,9 +42,21 @@ And then execute:
|
|
38
42
|
bundle
|
39
43
|
```
|
40
44
|
|
45
|
+
**Note:**
|
46
|
+
|
47
|
+
The correct version of FriendlySignup should resolved automatically by the Bundler.
|
48
|
+
However you can force some specific version using `gem "decidim-friendly_signup", "~> 0.1.0"` in the Gemfile.
|
49
|
+
|
50
|
+
Depending on your Decidim version, choose the corresponding FriendlySignup version to ensure compatibility:
|
51
|
+
|
52
|
+
| FriendlySignup version | Compatible Decidim versions |
|
53
|
+
|---|---|
|
54
|
+
| 0.2.x | 0.26.x |
|
55
|
+
| 0.1.x | 0.26.x |
|
56
|
+
|
41
57
|
## Configuration
|
42
58
|
|
43
|
-
Customize your integration by creating an initializer (ie: `config/initializes/friendly_signup.rb`) and set some of the variables:
|
59
|
+
Customize your integration by creating an initializer (ie: `config/initializes/friendly_signup.rb`) and set some of the variables (you don't need to do this if you want all features enabled):
|
44
60
|
|
45
61
|
```ruby
|
46
62
|
# config/initializers/friendly_signup.rb
|
@@ -48,14 +64,23 @@ Customize your integration by creating an initializer (ie: `config/initializes/f
|
|
48
64
|
Decidim::FriendlySignup.configure do |config|
|
49
65
|
# Override password views or leave the originals (default is true):
|
50
66
|
config.override_passwords = false
|
51
|
-
end
|
52
67
|
|
68
|
+
# Automatically validate user inputs in the register form (default is true):
|
69
|
+
config.use_instant_validation = false
|
70
|
+
end
|
53
71
|
```
|
54
72
|
|
55
73
|
## Contributing
|
56
74
|
|
57
75
|
Bug reports and pull requests are welcome on GitHub at https://github.com/OpenSourcePolitics/decidim-module-friendly_signup.
|
58
76
|
|
77
|
+
### Localization
|
78
|
+
|
79
|
+
If you would like to see this module in your own language, you can help with its
|
80
|
+
translation at Crowdin:
|
81
|
+
|
82
|
+
https://crowdin.com/project/decidim-friendly-signup
|
83
|
+
|
59
84
|
### Developing
|
60
85
|
|
61
86
|
To start contributing to this project, first:
|
@@ -133,23 +158,13 @@ commands shown above.
|
|
133
158
|
|
134
159
|
### Test code coverage
|
135
160
|
|
136
|
-
|
137
|
-
the `SIMPLECOV=1` environment variable in the rspec command as follows:
|
161
|
+
Test coverage should be generated automatically in the folder "coverage" once any test is run:
|
138
162
|
|
139
163
|
```bash
|
140
|
-
$
|
164
|
+
$ bundle exec rspec
|
165
|
+
$ firefox coverage/index.html
|
141
166
|
```
|
142
167
|
|
143
|
-
This will generate a folder named `coverage` in the project root which contains
|
144
|
-
the code coverage report.
|
145
|
-
|
146
|
-
### Localization
|
147
|
-
|
148
|
-
If you would like to see this module in your own language, you can help with its
|
149
|
-
translation at Crowdin:
|
150
|
-
|
151
|
-
https://crowdin.com/project/decidim-friendly-signup
|
152
|
-
|
153
168
|
## License
|
154
169
|
|
155
170
|
See [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt).
|
@@ -23,11 +23,8 @@ module Decidim
|
|
23
23
|
@snippets
|
24
24
|
end
|
25
25
|
|
26
|
-
def friendly_override_activated?(
|
27
|
-
|
28
|
-
when :override_passwords
|
29
|
-
Decidim::FriendlySignup.override_passwords.present?
|
30
|
-
end
|
26
|
+
def friendly_override_activated?(feat)
|
27
|
+
Decidim::FriendlySignup.send(feat.to_s).present?
|
31
28
|
end
|
32
29
|
end
|
33
30
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module FriendlySignup
|
5
|
+
class ValidatorController < ApplicationController
|
6
|
+
include Decidim::FormFactory
|
7
|
+
|
8
|
+
def validate
|
9
|
+
@form = form(Decidim::RegistrationForm).from_params(params)
|
10
|
+
validator = UserAttributeValidator.new(form: @form, attribute: params[:attribute])
|
11
|
+
render json: {
|
12
|
+
valid: validator.valid?,
|
13
|
+
error: validator.error
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
/* eslint-disable line-comment-position, no-ternary, no-inline-comments */
|
2
|
+
|
3
|
+
// Instant, server-side validation
|
4
|
+
// compatible with abide classes https://get.foundation/sites/docs/abide.html
|
5
|
+
export default class InstantValidator {
|
6
|
+
// ms before xhr check
|
7
|
+
static get TIMEOUT() {
|
8
|
+
return 150;
|
9
|
+
}
|
10
|
+
|
11
|
+
constructor($form) {
|
12
|
+
this.$form = $form;
|
13
|
+
this.$inputs = $form.find("[data-instant-attribute]");
|
14
|
+
this.url = this.$form.data("validationUrl");
|
15
|
+
}
|
16
|
+
|
17
|
+
init() {
|
18
|
+
// this final validation prevents abide from resetting the field when user loses focus
|
19
|
+
this.$inputs.on("blur", (evt) => {
|
20
|
+
this.validate($(evt.currentTarget));
|
21
|
+
});
|
22
|
+
this.$inputs.on("keyup", (evt) => {
|
23
|
+
let $input = $(evt.currentTarget);
|
24
|
+
let checkTimeout = $input.data("checkTimeout");
|
25
|
+
// Trigger live validation with a delay to avoid throttling
|
26
|
+
if (checkTimeout) {
|
27
|
+
clearTimeout(checkTimeout);
|
28
|
+
}
|
29
|
+
$input.data("checkTimeout", setTimeout(() => {
|
30
|
+
this.validate($input);
|
31
|
+
}, this.TIMEOUT)
|
32
|
+
);
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
value($input) {
|
37
|
+
return $input.val().trim();
|
38
|
+
}
|
39
|
+
|
40
|
+
attribute($input) {
|
41
|
+
return $input.data("instantAttribute");
|
42
|
+
}
|
43
|
+
|
44
|
+
target($input) {
|
45
|
+
const $target = this.$form.find($input.data("instantTarget"));
|
46
|
+
return $target.length
|
47
|
+
? $target
|
48
|
+
: $input;
|
49
|
+
}
|
50
|
+
|
51
|
+
validate($input) {
|
52
|
+
this.tamper($input);
|
53
|
+
this.post($input).done((response) => {
|
54
|
+
this.setFeedback(response, $input);
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
setFeedback(data, $input) {
|
59
|
+
if (data.valid) {
|
60
|
+
this.clearErrors($input);
|
61
|
+
} else {
|
62
|
+
this.addErrors(this.target($input), data.error);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
tamper($dest) {
|
67
|
+
$dest.data("tampered", $dest.val().trim() !== "");
|
68
|
+
}
|
69
|
+
|
70
|
+
isTampered($dest) {
|
71
|
+
return $dest.data("tampered");
|
72
|
+
}
|
73
|
+
|
74
|
+
addErrors($dest, msg) {
|
75
|
+
if ($dest.closest("label").find(".form-error").length > 1) {
|
76
|
+
// Decidim may add and additional error class that does not play well with abide
|
77
|
+
$dest.closest("label").find(".form-error:last").remove();
|
78
|
+
}
|
79
|
+
this.$form.foundation("addErrorClasses", $dest);
|
80
|
+
if (msg) {
|
81
|
+
$dest.closest("label").find(".form-error").text(msg);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
clearErrors($dest) {
|
86
|
+
this.$form.foundation("removeErrorClasses", $dest);
|
87
|
+
}
|
88
|
+
|
89
|
+
post($input) {
|
90
|
+
return $.ajax(this.url, {
|
91
|
+
method: "POST",
|
92
|
+
data: `${this.$form.serialize()}&attribute=${this.attribute($input)}`
|
93
|
+
});
|
94
|
+
}
|
95
|
+
}
|
File without changes
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import InstantValidator from "src/decidim/friendly_signup/lib/instant_validator";
|
2
|
+
|
3
|
+
$(() => {
|
4
|
+
window.Decidim = window.Decidim || {};
|
5
|
+
window.Decidim.instantValidator = new InstantValidator($("form.instant-validation"));
|
6
|
+
window.Decidim.instantValidator.init();
|
7
|
+
});
|
@@ -26,7 +26,7 @@
|
|
26
26
|
<div class="row">
|
27
27
|
<div class="columns large-6 medium-10 medium-centered">
|
28
28
|
|
29
|
-
<%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: registration_path(resource_name), html: { class: "register-form new_user", id: "register-form" }) do |f| %>
|
29
|
+
<%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: registration_path(resource_name), html: { class: "register-form new_user#{friendly_override_activated?(:use_instant_validation) && ' instant-validation'}", id: "register-form" }, data: { "validation-url": decidim_friendly_signup.validate_path }) do |f| %>
|
30
30
|
<%= invisible_captcha %>
|
31
31
|
<div class="card">
|
32
32
|
<div class="card__content">
|
@@ -34,21 +34,21 @@
|
|
34
34
|
|
35
35
|
<div class="user-person">
|
36
36
|
<div class="field">
|
37
|
-
<%= f.text_field :name, help_text: t(".username_help") %>
|
37
|
+
<%= f.text_field :name, help_text: t(".username_help"), autocomplete: "off" %>
|
38
38
|
</div>
|
39
39
|
</div>
|
40
40
|
|
41
41
|
<div class="user-nickname">
|
42
42
|
<div class="field">
|
43
|
-
<%= f.text_field :nickname, help_text: t(".nickname_help", organization: current_organization.name), prefix: { value: "@", small: 1, large: 1 } %>
|
43
|
+
<%= f.text_field :nickname, help_text: t(".nickname_help", organization: current_organization.name), prefix: { value: "@", small: 1, large: 1 }, autocomplete: "off" %>
|
44
44
|
</div>
|
45
45
|
</div>
|
46
46
|
|
47
47
|
<div class="field">
|
48
|
-
<%= f.email_field :email %>
|
48
|
+
<%= f.email_field :email, autocomplete: "email", data: { "instant-attribute": "email" } %>
|
49
49
|
</div>
|
50
50
|
|
51
|
-
<%= render("decidim/friendly_signup/shared/password_fields", form: f, options: { help_text: t(".password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH), autocomplete: "off" }) %>
|
51
|
+
<%= render("decidim/friendly_signup/shared/password_fields", form: f, options: { required: true, help_text: t(".password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH), autocomplete: "off", data: { "instant-attribute": "password" } }) %>
|
52
52
|
</div>
|
53
53
|
</div>
|
54
54
|
|
@@ -9,6 +9,10 @@ module Decidim
|
|
9
9
|
class Engine < ::Rails::Engine
|
10
10
|
isolate_namespace Decidim::FriendlySignup
|
11
11
|
|
12
|
+
routes do
|
13
|
+
post :validate, to: "validator#validate"
|
14
|
+
end
|
15
|
+
|
12
16
|
# Prepare a zone to create overrides
|
13
17
|
# https://edgeguides.rubyonrails.org/engines.html#overriding-models-and-controllers
|
14
18
|
# overrides
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module FriendlySignup
|
5
|
+
class UserAttributeValidator
|
6
|
+
def initialize(attribute:, form:)
|
7
|
+
@attribute = attribute
|
8
|
+
@form = form
|
9
|
+
end
|
10
|
+
|
11
|
+
delegate :current_organization, to: :form
|
12
|
+
attr_reader :attribute, :form
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
@valid ||= begin
|
16
|
+
form.validate
|
17
|
+
# we don't validate the form but the attribute alone
|
18
|
+
errors.blank?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def input
|
23
|
+
@input ||= form.public_send(attribute).to_s.dup if valid_attribute?
|
24
|
+
end
|
25
|
+
|
26
|
+
def errors
|
27
|
+
@errors ||= valid_attribute? ? form.errors[attribute] : ["Invalid attribute"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def error
|
31
|
+
errors.flatten.map(&:upcase_first).join(". ") unless valid?
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def valid_attribute?
|
37
|
+
%w(nickname email name password).include? attribute.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def valid_suggestor?
|
41
|
+
["nickname"].include? attribute.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid_users
|
45
|
+
Decidim::UserBaseEntity.where(invitation_token: nil, organization: current_organization)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,14 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "decidim/friendly_signup/version"
|
3
4
|
require "decidim/friendly_signup/engine"
|
4
5
|
|
5
6
|
module Decidim
|
6
7
|
module FriendlySignup
|
7
8
|
include ActiveSupport::Configurable
|
8
9
|
|
10
|
+
autoload :UserAttributeValidator, "decidim/friendly_signup/user_attribute_validator"
|
11
|
+
|
9
12
|
# Whether to override passwords boxes or not
|
10
13
|
config_accessor :override_passwords do
|
11
14
|
true
|
12
15
|
end
|
16
|
+
|
17
|
+
# Whether to use instant validation or not
|
18
|
+
config_accessor :use_instant_validation do
|
19
|
+
true
|
20
|
+
end
|
13
21
|
end
|
14
22
|
end
|
23
|
+
|
24
|
+
# Engines to handle logic unrelated to participatory spaces or components
|
25
|
+
Decidim.register_global_engine(
|
26
|
+
:decidim_friendly_signup, # this is the name of the global method to access engine routes
|
27
|
+
::Decidim::FriendlySignup::Engine,
|
28
|
+
at: "/friendly_signup"
|
29
|
+
)
|
data/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "decidim-module-friendly_signup",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.2.0",
|
4
4
|
"lockfileVersion": 2,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "decidim-module-friendly_signup",
|
9
|
-
"version": "0.
|
9
|
+
"version": "0.2.0",
|
10
10
|
"license": "AGPL-3.0-or-later",
|
11
11
|
"devDependencies": {
|
12
12
|
"eslint": "^7.25.0",
|
data/package.json
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decidim-friendly_signup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Vergés
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: decidim-core
|
@@ -49,11 +49,15 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
51
|
- app/controllers/concerns/decidim/friendly_signup/needs_header_snippets.rb
|
52
|
+
- app/controllers/decidim/friendly_signup/application_controller.rb
|
53
|
+
- app/controllers/decidim/friendly_signup/validator_controller.rb
|
52
54
|
- app/packs/entrypoints/decidim_friendly_signup.js
|
53
55
|
- app/packs/entrypoints/decidim_friendly_signup.scss
|
54
56
|
- app/packs/images/decidim/friendly_signup/icon.svg
|
55
|
-
- app/packs/src/decidim/friendly_signup/
|
56
|
-
- app/packs/src/decidim/friendly_signup/password_toggler.js
|
57
|
+
- app/packs/src/decidim/friendly_signup/lib/instant_validator.js
|
58
|
+
- app/packs/src/decidim/friendly_signup/lib/password_toggler.js
|
59
|
+
- app/packs/src/decidim/friendly_signup/setup_password.js
|
60
|
+
- app/packs/src/decidim/friendly_signup/setup_validations.js
|
57
61
|
- app/packs/stylesheets/decidim/friendly_signup/_input-groups.scss
|
58
62
|
- app/views/decidim/account/_password_fields.html.erb
|
59
63
|
- app/views/decidim/devise/invitations/edit.html.erb
|
@@ -65,6 +69,7 @@ files:
|
|
65
69
|
- config/locales/en.yml
|
66
70
|
- lib/decidim/friendly_signup.rb
|
67
71
|
- lib/decidim/friendly_signup/engine.rb
|
72
|
+
- lib/decidim/friendly_signup/user_attribute_validator.rb
|
68
73
|
- lib/decidim/friendly_signup/version.rb
|
69
74
|
- package-lock.json
|
70
75
|
- package.json
|