From b19c78c756aecb3a6fb94639a9adb7603cef1b42 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 10:36:41 +0100 Subject: [PATCH 01/12] [bug] select all plans for slot restriction When using the 'select all' button, to restrict an availbility to subscribers, all plans are selected, even those disabled --- CHANGELOG.md | 1 + app/frontend/src/javascript/controllers/admin/calendar.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2085a0b..65480407e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - More explanations in the setup script - Send pre-compressed assets to the browsers instead of the regular ones - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled +- Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans - Fix a security issue: updated elliptic to 6.5.4 to fix [CVE-2020-28498](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498) - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash` - [TODO DEPLOY] `rails db:seed` diff --git a/app/frontend/src/javascript/controllers/admin/calendar.js b/app/frontend/src/javascript/controllers/admin/calendar.js index 3f84b0d35..79cf9a094 100644 --- a/app/frontend/src/javascript/controllers/admin/calendar.js +++ b/app/frontend/src/javascript/controllers/admin/calendar.js @@ -665,7 +665,7 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui $scope.selectedPlans = []; $scope.selectedPlansBinding = {}; if (count === 0) { - plansPromise.forEach(function (plan) { + plansPromise.filter(p => !p.disabled).forEach(function (plan) { $scope.selectedPlans.push(plan); $scope.selectedPlansBinding[plan.id] = true; }); From e9185bd40259ab223e4b05715b48740ffb31f750 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 10:43:45 +0100 Subject: [PATCH 02/12] [bug] recurring availabilities are not restricted to subscribers --- CHANGELOG.md | 1 + app/services/availabilities/create_availabilities_service.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65480407e..d51293357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Send pre-compressed assets to the browsers instead of the regular ones - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled - Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans +- Fix a bug: recurring availabilities are not restricted to subscribers - Fix a security issue: updated elliptic to 6.5.4 to fix [CVE-2020-28498](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498) - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash` - [TODO DEPLOY] `rails db:seed` diff --git a/app/services/availabilities/create_availabilities_service.rb b/app/services/availabilities/create_availabilities_service.rb index da8891642..fb5f54474 100644 --- a/app/services/availabilities/create_availabilities_service.rb +++ b/app/services/availabilities/create_availabilities_service.rb @@ -22,7 +22,8 @@ class Availabilities::CreateAvailabilitiesService space_ids: availability.space_ids, tag_ids: availability.tag_ids, nb_total_places: availability.nb_total_places, - slot_duration: availability.slot_duration + slot_duration: availability.slot_duration, + plan_ids: availability.plan_ids ).save! end end From ef32532cf5c9ac9d942e5c77df4b8a6f533b1018 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 11:32:04 +0100 Subject: [PATCH 03/12] Links created using medium editor opens in new tabs --- CHANGELOG.md | 1 + app/frontend/templates/admin/plans/_form.html | 10 +++- .../templates/admin/settings/about.html | 21 +++++-- .../templates/admin/settings/general.html | 60 +++++++++++++------ .../templates/admin/settings/home_page.html | 11 +++- 5 files changed, 74 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d51293357..ec7790417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - In the email notification, sent to admins on account creation, show the group of the user - More explanations in the setup script - Send pre-compressed assets to the browsers instead of the regular ones +- Links created using "medium editor" opens in new tabs - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled - Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans - Fix a bug: recurring availabilities are not restricted to subscribers diff --git a/app/frontend/templates/admin/plans/_form.html b/app/frontend/templates/admin/plans/_form.html index 7161b264e..8cfdcbcca 100644 --- a/app/frontend/templates/admin/plans/_form.html +++ b/app/frontend/templates/admin/plans/_form.html @@ -130,9 +130,13 @@
-
+
diff --git a/app/frontend/templates/admin/settings/about.html b/app/frontend/templates/admin/settings/about.html index 109f3d330..67a0c98ba 100644 --- a/app/frontend/templates/admin/settings/about.html +++ b/app/frontend/templates/admin/settings/about.html @@ -30,18 +30,27 @@
-
+
{{ 'app.admin.settings.drag_and_drop_to_insert_images' | translate }}
-
+
{{ 'app.admin.settings.shift_enter_to_force_carriage_return' | translate }} diff --git a/app/frontend/templates/admin/settings/general.html b/app/frontend/templates/admin/settings/general.html index 611235b51..ff9c0e9aa 100644 --- a/app/frontend/templates/admin/settings/general.html +++ b/app/frontend/templates/admin/settings/general.html @@ -48,52 +48,76 @@

{{ 'app.admin.settings.message_of_the_machine_booking_page' }}

-
+

{{ 'app.admin.settings.warning_message_of_the_training_booking_page'}}

-
+

{{ 'app.admin.settings.information_message_of_the_training_reservation_page'}}

-
+

{{ 'app.admin.settings.message_of_the_subscriptions_page' }}

-
+

{{ 'app.admin.settings.message_of_the_events_page' }}

-
+

{{ 'app.admin.settings.message_of_the_spaces_page' }}

-
+
diff --git a/app/frontend/templates/admin/settings/home_page.html b/app/frontend/templates/admin/settings/home_page.html index 40de310f7..4b4c858c1 100644 --- a/app/frontend/templates/admin/settings/home_page.html +++ b/app/frontend/templates/admin/settings/home_page.html @@ -14,8 +14,15 @@

{{ 'app.admin.settings.news_of_the_home_page' }}

-
+
+
{{ 'app.admin.settings.leave_it_empty_to_not_bring_up_any_news_on_the_home_page' | translate }}
From 39a7e238811c4414e3dcf14903ee4670640b6790 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 13:13:51 +0100 Subject: [PATCH 04/12] Improved style of public plans page --- CHANGELOG.md | 2 + .../src/stylesheets/app.components.scss | 130 +++--------------- app/frontend/src/stylesheets/application.scss | 1 + .../src/stylesheets/modules/plan-card.scss | 102 ++++++++++++++ app/frontend/templates/plans/_plan.html | 34 ++--- app/frontend/templates/plans/index.html | 17 +-- app/themes/casemate/style.scss.erb | 24 ++-- test/fixtures/stylesheets.yml | 6 +- 8 files changed, 157 insertions(+), 159 deletions(-) create mode 100644 app/frontend/src/stylesheets/modules/plan-card.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index ec7790417..2dee75bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,14 @@ - More explanations in the setup script - Send pre-compressed assets to the browsers instead of the regular ones - Links created using "medium editor" opens in new tabs +- Improved style of public plans page - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled - Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans - Fix a bug: recurring availabilities are not restricted to subscribers - Fix a security issue: updated elliptic to 6.5.4 to fix [CVE-2020-28498](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498) - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash` - [TODO DEPLOY] `rails db:seed` +- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet` ## v4.7.5 2021 March 08 - Fix a bug: unable to compile the assets during the upgrade, if the env file has some whitespaces around the equal sign diff --git a/app/frontend/src/stylesheets/app.components.scss b/app/frontend/src/stylesheets/app.components.scss index 3d52a94c2..04d1e6691 100644 --- a/app/frontend/src/stylesheets/app.components.scss +++ b/app/frontend/src/stylesheets/app.components.scss @@ -267,125 +267,31 @@ } } -.pricing-panel { - border: 1px solid $border-color; - height: 391px; - - &:first-child { - border-right: none; - - @include border-radius(3px 0 0 3px); +.list-of-plans { + .group-title { + width: 83.33%; + border-bottom: 1px solid; + padding-bottom: 2em; + margin: auto auto 1em; } - &:last-child { - @include border-radius(0 3px 3px 0); - } - - .plan-card { - height: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - } - - .title { - margin: 10px 0; - font-size: rem-calc(16); - text-transform: uppercase; - color: black; - } - - .content { - padding: 15px 0; - background-color: $bg-gray; - - .wrap, .wrap-monthly { - width: 130px; - height: 130px; - display: inline-block; - background: white; - - @include border-radius(50%, 50%, 50%, 50%); - - border: 3px solid; - - .price { - width: 114px; - display: flex; - flex-direction: column; - justify-content: center; - - @include border-radius(50%, 50%, 50%, 50%); - } + .plans-per-group { + & { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + border: 1px solid transparent; } - .wrap-monthly { - & > .price { - & > .amount { - padding-top: 4px; - line-height: 1.2em; - } - - & > .period { - padding-top: 4px; - } - } - } - .price { - position: relative; - top: 5px; - left: 5px; - height: 114px; - background-color: black; - - .amount { - padding-left: 4px; - padding-right: 4px; - font-weight: bold; - font-size: rem-calc(17); - color: white; - } - - .period { - position: relative; - top: -6px; - font-size: rem-calc(14); - color: white; - } - } - } - - .card-footer { - display: flex; - flex-direction: column; - justify-content: space-around; - height: 100%; - - .plan-description { - max-height: 5.2em; - overflow: hidden; + & > * { + width: 50%; } - .cta-button { - margin: 20px 0; - - .subscribe-button { - @extend .btn; - @extend .rounded; - - outline: 0; - font-weight: 600; - font-size: rem-calc(16); - background-color: white; - padding-left: 30px; - padding-right: 30px; + @media screen and (max-width: 992px) { + & > * { + width: 100%; } - button.subscribe-button:focus, button.subscribe-button:hover { - outline: 0; - } - } - .info-link { - margin-top: 1em; } } } diff --git a/app/frontend/src/stylesheets/application.scss b/app/frontend/src/stylesheets/application.scss index fac4aacf6..e07995746 100644 --- a/app/frontend/src/stylesheets/application.scss +++ b/app/frontend/src/stylesheets/application.scss @@ -32,5 +32,6 @@ @import "modules/payment-schedules-list"; @import "modules/stripe-confirm"; @import "modules/payment-schedule-dashboard"; +@import "modules/plan-card"; @import "app.responsive"; diff --git a/app/frontend/src/stylesheets/modules/plan-card.scss b/app/frontend/src/stylesheets/modules/plan-card.scss new file mode 100644 index 000000000..71c4fcb0b --- /dev/null +++ b/app/frontend/src/stylesheets/modules/plan-card.scss @@ -0,0 +1,102 @@ +.plan-card { + display: block; + height: 100%; + width: 100%; + + .title { + margin: 10px 0; + font-size: 1.6rem; + text-transform: uppercase; + } + + .content { + & { + padding: 15px 0; + background-color: #f5f5f5; + } + + .wrap, .wrap-monthly { + width: 130px; + height: 130px; + display: inline-block; + background: white; + + @include border-radius(50%, 50%, 50%, 50%); + + border: 3px solid; + + .price { + width: 114px; + display: flex; + flex-direction: column; + justify-content: center; + + @include border-radius(50%, 50%, 50%, 50%); + } + } + + .wrap-monthly { + & > .price { + & > .amount { + padding-top: 4px; + line-height: 1.2em; + } + + & > .period { + padding-top: 4px; + } + } + } + .price { + position: relative; + top: 5px; + left: 5px; + height: 114px; + background-color: black; + + .amount { + padding-left: 4px; + padding-right: 4px; + font-weight: bold; + font-size: rem-calc(17); + color: white; + } + + .period { + position: relative; + top: -6px; + font-size: rem-calc(14); + color: white; + } + } + } + + .card-footer { + .plan-description { + + & p:nth-child(2n+3), p:nth-child(2n+4) { + display: none; + } + } + .cta-button { + margin: 20px 0; + + .subscribe-button { + @extend .btn; + @extend .rounded; + outline: 0; + font-weight: 600; + font-size: rem-calc(16); + background-color: white; + padding-left: 30px; + padding-right: 30px; + } + button.subscribe-button:focus, button.subscribe-button:hover { + outline: 0; + } + } + .info-link { + margin-top: 1em; + } + } +} diff --git a/app/frontend/templates/plans/_plan.html b/app/frontend/templates/plans/_plan.html index 359b55525..56a3b0f70 100644 --- a/app/frontend/templates/plans/_plan.html +++ b/app/frontend/templates/plans/_plan.html @@ -1,33 +1,25 @@ -
+
-

{{ plansGroup.name }}

+

{{ plansGroup.name }}

-
+ + {{ 'app.shared.plan_subscribe.do_not_subscribe' | translate }} +
diff --git a/app/frontend/templates/plans/index.html b/app/frontend/templates/plans/index.html index 0706c9c6e..a5d81fbfa 100644 --- a/app/frontend/templates/plans/index.html +++ b/app/frontend/templates/plans/index.html @@ -14,31 +14,26 @@ -
+
-

{{plansGroup.name}}

+

{{plansGroup.name}}

-
+
- -
- - + is-selected="isSelected(plan)" -
diff --git a/app/themes/casemate/style.scss.erb b/app/themes/casemate/style.scss.erb index 28e1e9b6a..0caae8bc3 100644 --- a/app/themes/casemate/style.scss.erb +++ b/app/themes/casemate/style.scss.erb @@ -88,7 +88,7 @@ a { .app-generator a, .home-events h4 a, a.reinit-filters, -.pricing-panel a, +.plan-card a, .calendar-url a, .article a, a.project-author, @@ -103,7 +103,7 @@ a.collected-infos { .app-generator a:hover, .home-events h4 a:hover, a.reinit-filters:hover, -.pricing-panel a:hover, +.plan-card a:hover, .calendar-url a:hover, .article a:hover, a.project-author:hover, @@ -254,19 +254,19 @@ h5:after { color: $secondary-text-color; } -.pricing-panel .plan-card .content .wrap, -.pricing-panel .plan-card .content .wrap-monthly { - border-color: $secondary; +.plan-card .content .wrap, +.plan-card .content .wrap-monthly { + border-color: $secondary !important; } -.pricing-panel .plan-card .content .price { - background-color: $primary; - color: $primary-text-color; +.plan-card .content .price { + background-color: $primary !important; + color: $primary-text-color !important; } -.pricing-panel .card-footer .cta-button .btn:hover, -.pricing-panel .card-footer .cta-button .custom-invoice .modal-body .elements li:hover, -.custom-invoice .modal-body .elements .pricing-panel .card-footer .cta-button li:hover { +.plan-card .card-footer .cta-button .btn:hover, +.plan-card .card-footer .cta-button .custom-invoice .modal-body .elements li:hover, +.custom-invoice .modal-body .elements .plan-card .card-footer .cta-button li:hover { background-color: $secondary !important; color: $secondary-text-color; } @@ -306,7 +306,7 @@ section#cookies-modal div.cookies-consent .cookies-actions button.accept { color: $secondary-text-color; } -.pricing-panel { +.plan-card { .card-footer { .cta-button { button.subscribe-button { diff --git a/test/fixtures/stylesheets.yml b/test/fixtures/stylesheets.yml index 182cefe56..a0a42cbca 100644 --- a/test/fixtures/stylesheets.yml +++ b/test/fixtures/stylesheets.yml @@ -31,8 +31,8 @@ stylesheet_1: .btn-warning:hover, .editable-buttons button[type=submit].btn-primary:hover, .btn-warning:focus, .editable-buttons button[type=submit].btn-primary:focus, .btn-warning.focus, .editable-buttons button.focus[type=submit].btn-primary, .btn-warning:active, .editable-buttons button[type=submit].btn-primary:active, .btn-warning.active, .editable-buttons button.active[type=submit].btn-primary, .open > .btn-warning.dropdown-toggle, .editable-buttons .open > button.dropdown-toggle[type=submit].btn-primary { background-color: #998500 !important; border-color: #998500 !important; } .btn-warning-full { border-color: #ffdd00; background-color: #ffdd00; } .heading .heading-btn a:hover { background-color: #ffdd00; } - .pricing-panel .content .wrap { border-color: #ffdd00; } - .pricing-panel .cta-button .btn:hover, .pricing-panel .cta-button .custom-invoice .modal-body .elements li:hover, .custom-invoice .modal-body .elements .pricing-panel .cta-button li:hover { background-color: #ffdd00 !important; } + .plan-card .content .wrap { border-color: #ffdd00; } + .plan-card .cta-button .btn:hover, .plan-card .cta-button .custom-invoice .modal-body .elements li:hover, .custom-invoice .modal-body .elements .plan-card .cta-button li:hover { background-color: #ffdd00 !important; } a.label:hover, .form-control.form-control-ui-select .select2-choices a.select2-search-choice:hover, a.label:focus, .form-control.form-control-ui-select .select2-choices a.select2-search-choice:focus { color: #cb1117; } .about-picture { background: linear-gradient( rgba(255,255,255,0.12), rgba(255,255,255,0.13) ), linear-gradient( rgba(203, 17, 23, 0.78), rgba(203, 17, 23, 0.82) ), url('/about-fablab.jpg') no-repeat; } .social-icons > div:hover { background-color: #ffdd00; } @@ -46,4 +46,4 @@ stylesheet_1: stylesheet_2: id: 2 contents: ".home-page { }" - name: home_page \ No newline at end of file + name: home_page From a5b3728f8cb1dd30507be436ddbdc87b6318adcb Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 17:42:54 +0100 Subject: [PATCH 05/12] [bug] various fixes on accouting exports - accounting exports may ignore some invoices for the first and last days - file caching for accounring exports is not used --- CHANGELOG.md | 2 ++ app/controllers/api/accounting_exports_controller.rb | 2 +- app/frontend/src/javascript/controllers/admin/invoices.js | 5 ++--- app/services/accounting_export_service.rb | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dee75bf6..5e5dab41e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled - Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans - Fix a bug: recurring availabilities are not restricted to subscribers +- Fix a bug: accounting exports may ignore some invoices for the first and last days +- Fix a bug: accounting export caching is not working - Fix a security issue: updated elliptic to 6.5.4 to fix [CVE-2020-28498](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498) - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash` - [TODO DEPLOY] `rails db:seed` diff --git a/app/controllers/api/accounting_exports_controller.rb b/app/controllers/api/accounting_exports_controller.rb index 24d15492a..20dd342dd 100644 --- a/app/controllers/api/accounting_exports_controller.rb +++ b/app/controllers/api/accounting_exports_controller.rb @@ -8,7 +8,7 @@ class API::AccountingExportsController < API::ApiController def export authorize :accounting_export - export = Export.where(category: 'accounting', export_type: 'accounting-software', key: params[:key]) + export = Export.where(category: 'accounting', export_type: params[:type], key: params[:key]) .where(extension: params[:extension], query: params[:query]) .where('created_at > ?', Invoice.maximum('updated_at')) .last diff --git a/app/frontend/src/javascript/controllers/admin/invoices.js b/app/frontend/src/javascript/controllers/admin/invoices.js index 168e42089..31a0a240a 100644 --- a/app/frontend/src/javascript/controllers/admin/invoices.js +++ b/app/frontend/src/javascript/controllers/admin/invoices.js @@ -1309,8 +1309,8 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope', columns: $scope.exportTarget.settings.columns, encoding: $scope.exportTarget.settings.encoding, date_format: $scope.exportTarget.settings.dateFormat, - start_date: $scope.exportTarget.startDate, - end_date: $scope.exportTarget.endDate, + start_date: moment.utc($scope.exportTarget.startDate).startOf('day').toISOString(), + end_date: moment.utc($scope.exportTarget.endDate).endOf('day').toISOString(), label_max_length: $scope.exportTarget.settings.labelMaxLength, decimal_separator: $scope.exportTarget.settings.decimalSeparator, export_invoices_at_zero: $scope.exportTarget.settings.exportInvoicesAtZero @@ -1370,7 +1370,6 @@ Application.Controllers.controller('StripeKeysModalController', ['$scope', '$uib $scope.publicKeyStatus = false; return; } - const today = new Date(); $http({ method: 'POST', url: 'https://api.stripe.com/v1/tokens', diff --git a/app/services/accounting_export_service.rb b/app/services/accounting_export_service.rb index f3986f75a..c86797b1a 100644 --- a/app/services/accounting_export_service.rb +++ b/app/services/accounting_export_service.rb @@ -33,6 +33,7 @@ class AccountingExportService invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC') invoices = invoices.where('total > 0') unless export_zeros invoices.each do |i| + puts "processing invoice #{i.id}..." content << generate_rows(i) end From f535be5b0561c25dc840bcc38460b8ff3c3532bf Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 22 Mar 2021 18:02:56 +0100 Subject: [PATCH 06/12] WIP: address_required --- .../src/javascript/controllers/application.js.erb | 5 ++++- app/frontend/src/javascript/controllers/profile.js | 9 ++++++--- app/frontend/src/javascript/models/setting.ts | 5 ++++- app/frontend/src/javascript/router.js | 5 ++--- app/frontend/templates/admin/settings/general.html | 12 ++++++++++++ app/models/invoicing_profile.rb | 2 ++ app/models/setting.rb | 3 ++- app/models/user.rb | 3 ++- app/policies/setting_policy.rb | 2 +- config/locales/app.admin.en.yml | 4 ++++ config/locales/app.admin.fr.yml | 3 +++ 11 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/frontend/src/javascript/controllers/application.js.erb b/app/frontend/src/javascript/controllers/application.js.erb index c25601eb5..e3dd67d92 100644 --- a/app/frontend/src/javascript/controllers/application.js.erb +++ b/app/frontend/src/javascript/controllers/application.js.erb @@ -92,7 +92,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco templateUrl: '/shared/signupModal.html', size: 'md', resolve: { - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'recaptcha_site_key', 'confirmation_required']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'recaptcha_site_key', 'confirmation_required', 'address_required']" }).$promise; }] }, controller: ['$scope', '$uibModalInstance', 'Group', 'CustomAsset', 'settingsPromise', 'growl', '_t', function ($scope, $uibModalInstance, Group, CustomAsset, settingsPromise, growl, _t) { // default parameters for the date picker in the account creation modal @@ -107,6 +107,9 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco // is the phone number required to sign-up? $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + // is the address required to sign-up? + $scope.addressRequired = (settingsPromise.address_required === 'true'); + // reCaptcha v2 site key (or undefined) $scope.recaptchaSiteKey = settingsPromise.recaptcha_site_key; diff --git a/app/frontend/src/javascript/controllers/profile.js b/app/frontend/src/javascript/controllers/profile.js index e7fcf4788..cba08dba6 100644 --- a/app/frontend/src/javascript/controllers/profile.js +++ b/app/frontend/src/javascript/controllers/profile.js @@ -13,8 +13,8 @@ 'use strict'; -Application.Controllers.controller('CompleteProfileController', ['$scope', '$rootScope', '$state', '$window', '_t', 'growl', 'CSRF', 'Auth', 'Member', 'settingsPromise', 'activeProviderPromise', 'groupsPromise', 'cguFile', 'memberPromise', 'Session', 'dialogs', 'AuthProvider', 'phoneRequiredPromise', - function ($scope, $rootScope, $state, $window, _t, growl, CSRF, Auth, Member, settingsPromise, activeProviderPromise, groupsPromise, cguFile, memberPromise, Session, dialogs, AuthProvider, phoneRequiredPromise) { +Application.Controllers.controller('CompleteProfileController', ['$scope', '$rootScope', '$state', '$window', '_t', 'growl', 'CSRF', 'Auth', 'Member', 'settingsPromise', 'activeProviderPromise', 'groupsPromise', 'cguFile', 'memberPromise', 'Session', 'dialogs', 'AuthProvider', + function ($scope, $rootScope, $state, $window, _t, growl, CSRF, Auth, Member, settingsPromise, activeProviderPromise, groupsPromise, cguFile, memberPromise, Session, dialogs, AuthProvider) { /* PUBLIC SCOPE */ // API URL where the form will be posted @@ -48,7 +48,10 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo $scope.cgu = cguFile.custom_asset; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _member_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // Angular-Bootstrap datepicker configuration for birthday $scope.datePicker = { diff --git a/app/frontend/src/javascript/models/setting.ts b/app/frontend/src/javascript/models/setting.ts index b42653b85..ccde19dc3 100644 --- a/app/frontend/src/javascript/models/setting.ts +++ b/app/frontend/src/javascript/models/setting.ts @@ -98,7 +98,10 @@ export enum SettingName { ConfirmationRequired = 'confirmation_required', WalletModule = 'wallet_module', StatisticsModule = 'statistics_module', - UpcomingEventsShown = 'upcoming_events_shown' + UpcomingEventsShown = 'upcoming_events_shown', + PaymentSchedulePrefix = 'payment_schedule_prefix', + TrainingsModule = 'trainings_module', + AddressRequired = 'address_required' } export interface Setting { diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index 5b2b67dbd..b1f5540ba 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -130,12 +130,11 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre']" }).$promise; }], + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre', 'phone_required', 'address_required']" }).$promise; }], activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }], groupsPromise: ['Group', function (Group) { return Group.query().$promise; }], cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise; }], - memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }], - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }] } }) diff --git a/app/frontend/templates/admin/settings/general.html b/app/frontend/templates/admin/settings/general.html index ff9c0e9aa..454672502 100644 --- a/app/frontend/templates/admin/settings/general.html +++ b/app/frontend/templates/admin/settings/general.html @@ -424,6 +424,18 @@
+
+

{{ 'app.admin.settings.address' }}

+

+ {{ 'app.admin.settings.address_required_info' }} +

+
+ + +
+

{{ 'app.admin.settings.captcha' }}

diff --git a/app/models/invoicing_profile.rb b/app/models/invoicing_profile.rb index ed2b21fe0..963e8790f 100644 --- a/app/models/invoicing_profile.rb +++ b/app/models/invoicing_profile.rb @@ -20,6 +20,8 @@ class InvoicingProfile < ApplicationRecord has_many :operated_invoices, foreign_key: :operator_profile_id, class_name: 'Invoice', dependent: :nullify has_many :operated_payment_schedules, foreign_key: :operator_profile_id, class_name: 'PaymentSchedule', dependent: :nullify + validates :address, presence: true, if: -> { Setting.get('address_required') } + def full_name # if first_name or last_name is nil, the empty string will be used as a temporary replacement (first_name || '').humanize.titleize + ' ' + (last_name || '').humanize.titleize diff --git a/app/models/setting.rb b/app/models/setting.rb index d83d35101..f2e34af1a 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -108,7 +108,8 @@ class Setting < ApplicationRecord statistics_module upcoming_events_shown payment_schedule_prefix - trainings_module] } + trainings_module + address_required] } # WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist def value diff --git a/app/models/user.rb b/app/models/user.rb index 23372aa39..01307ab03 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -203,7 +203,8 @@ class User < ApplicationRecord def need_completion? statistic_profile.gender.nil? || profile.first_name.blank? || profile.last_name.blank? || username.blank? || email.blank? || encrypted_password.blank? || group_id.nil? || statistic_profile.birthday.blank? || - (Setting.get('phone_required') && profile.phone.blank?) + (Setting.get('phone_required') && profile.phone.blank?) || + (Setting.get('address_required') && invoicing_profile.address&.address&.blank?) end ## Retrieve the requested data in the User and user's Profile tables diff --git a/app/policies/setting_policy.rb b/app/policies/setting_policy.rb index c24709daf..491f8c8a7 100644 --- a/app/policies/setting_policy.rb +++ b/app/policies/setting_policy.rb @@ -38,7 +38,7 @@ class SettingPolicy < ApplicationPolicy fablab_name name_genre event_explications_alert space_explications_alert link_name home_content phone_required tracking_id book_overlapping_slots slot_duration events_in_calendar spaces_module plans_module invoicing_module recaptcha_site_key feature_tour_display disqus_shortname allowed_cad_extensions openlab_app_id openlab_default - online_payment_module stripe_public_key confirmation_required wallet_module trainings_module] + online_payment_module stripe_public_key confirmation_required wallet_module trainings_module address_required] end ## diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 77f427439..921822901 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1073,6 +1073,7 @@ en: machines_sort_by: "machines display order" fab_analytics: "Fab Analytics" phone_required: "phone required" + address_required: "address required" tracking_id: "tracking ID" facebook_app_id: "Facebook App ID" twitter_analytics: "Twitter analytics account" @@ -1109,6 +1110,9 @@ en: phone: "Phone" phone_is_required: "Phone required" phone_required_info: "You can define if the phone number should be required to register a new user on Fab-manager." + address: "Address" + address_required_info: "You can define if the address should be required to register a new user on Fab-manager. Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." + address_is_required: "Address is required" captcha: "Captcha" captcha_info_html: "You can setup a protection against robots, to prevent them creating members accounts. This protection is using Google reCAPTCHA. Sign up for an API key pair to start using the captcha." site_key: "Site key" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index 1af569356..a98083288 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1109,6 +1109,9 @@ fr: phone: "Téléphone" phone_is_required: "Téléphone requis" phone_required_info: "Vous pouvez définir si le numéro de téléphone doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager." + address: "Adresse" + address_required_info: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager. Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." + address_is_required: "Adresse requise" captcha: "Captcha" captcha_info_html: "Vous pouvez mettre en place une protection contre les robots, pour les empêcher de créer des comptes membre. Cette protection utilise Google reCAPTCHA. Inscrivez vous pour obtenir une paire de clefs d'API afin d'utiliser le captcha." site_key: "Clef de site" From 7099f1f317d2584eb2c31bce32779206d8ba185a Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 23 Mar 2021 11:49:05 +0100 Subject: [PATCH 07/12] address required - Ability to set the address as a mandatory field - The address is new requested when creating an account - The profile completion page is less fuzzy for people landing on it without enabled SSO --- CHANGELOG.md | 3 +++ .../api/auth_providers_controller.rb | 1 + app/controllers/application_controller.rb | 3 ++- .../javascript/controllers/admin/members.js | 27 ++++++++++++------- .../src/javascript/controllers/members.js | 9 ++++--- .../src/javascript/controllers/profile.js | 8 ++++++ app/frontend/src/javascript/router.js | 10 +++---- .../templates/admin/settings/general.html | 2 +- app/frontend/templates/profile/complete.html | 16 +++++------ .../templates/shared/_member_form.html | 5 ++-- .../templates/shared/signupModal.html | 18 +++++++++++++ app/models/auth_provider.rb | 5 ++++ .../_auth_provider.json.jbuilder | 4 ++- .../api/auth_providers/active.json.jbuilder | 5 ++++ config/locales/app.admin.en.yml | 2 +- config/locales/app.admin.fr.yml | 3 ++- config/locales/app.public.en.yml | 2 ++ config/locales/app.public.fr.yml | 2 ++ lib/tasks/fablab/auth.rake | 2 +- 19 files changed, 94 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e5dab41e..ee6ab44c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next release - Ability to disable the trainings module +- Ability to set the address as a mandatory field +- The address is new requested when creating an account +- The profile completion page is less fuzzy for people landing on it without enabled SSO - Prevent showing error message when testing for old versions during upgrade - In the email notification, sent to admins on account creation, show the group of the user - More explanations in the setup script diff --git a/app/controllers/api/auth_providers_controller.rb b/app/controllers/api/auth_providers_controller.rb index 1efd31c44..6a4b5bea0 100644 --- a/app/controllers/api/auth_providers_controller.rb +++ b/app/controllers/api/auth_providers_controller.rb @@ -49,6 +49,7 @@ class API::AuthProvidersController < API::ApiController def active authorize AuthProvider @provider = AuthProvider.active + @previous = AuthProvider.previous end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 181777e43..10b7c224b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -41,7 +41,8 @@ class ApplicationController < ActionController::Base { profile_attributes: %i[phone last_name first_name interest software_mastered], invoicing_profile_attributes: [ - organization_attributes: [:name, address_attributes: [:address]] + organization_attributes: [:name, address_attributes: [:address]], + address_attributes: [:address] ], statistic_profile_attributes: %i[gender birthday] }, diff --git a/app/frontend/src/javascript/controllers/admin/members.js b/app/frontend/src/javascript/controllers/admin/members.js index 505076714..ad5e718db 100644 --- a/app/frontend/src/javascript/controllers/admin/members.js +++ b/app/frontend/src/javascript/controllers/admin/members.js @@ -650,8 +650,8 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', /** * Controller used in the member edition page */ -Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'phoneRequiredPromise', - function ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, phoneRequiredPromise) { +Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'settingsPromise', + function ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, settingsPromise) { /* PUBLIC SCOPE */ // API URL where the form will be posted @@ -670,7 +670,10 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _member_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // the user subscription if (($scope.user.subscribed_plan != null) && ($scope.user.subscription != null)) { @@ -990,8 +993,8 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', /** * Controller used in the member's creation page (admin view) */ -Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF', 'phoneRequiredPromise', - function ($scope, $state, $stateParams, Member, Training, Group, CSRF, phoneRequiredPromise) { +Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF', 'settingsPromise', + function ($scope, $state, $stateParams, Member, Training, Group, CSRF, settingsPromise) { CSRF.setMetaTags(); /* PUBLIC SCOPE */ @@ -1006,7 +1009,10 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', ' $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required to sign-up? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // Default member's profile parameters $scope.user = { @@ -1109,8 +1115,8 @@ Application.Controllers.controller('ImportMembersResultController', ['$scope', ' /** * Controller used in the admin creation page (admin view) */ -Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'Admin', 'growl', '_t', 'phoneRequiredPromise', - function ($state, $scope, Admin, growl, _t, phoneRequiredPromise) { +Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'Admin', 'growl', '_t', 'settingsPromise', + function ($state, $scope, Admin, growl, _t, settingsPromise) { // default admin profile let getGender; $scope.admin = { @@ -1131,7 +1137,10 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A }; // is the phone number required in _admin_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _admin_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); /** * Shows the birthday datepicker diff --git a/app/frontend/src/javascript/controllers/members.js b/app/frontend/src/javascript/controllers/members.js index 2b23102ee..05c233fe0 100644 --- a/app/frontend/src/javascript/controllers/members.js +++ b/app/frontend/src/javascript/controllers/members.js @@ -72,8 +72,8 @@ Application.Controllers.controller('MembersController', ['$scope', 'Member', 'me /** * Controller used when editing the current user's profile (in dashboard) */ -Application.Controllers.controller('EditProfileController', ['$scope', '$rootScope', '$state', '$window', '$sce', '$cookies', '$injector', 'Member', 'Auth', 'Session', 'activeProviderPromise', 'phoneRequiredPromise', 'growl', 'dialogs', 'CSRF', 'memberPromise', 'groups', '_t', - function ($scope, $rootScope, $state, $window, $sce, $cookies, $injector, Member, Auth, Session, activeProviderPromise, phoneRequiredPromise, growl, dialogs, CSRF, memberPromise, groups, _t) { +Application.Controllers.controller('EditProfileController', ['$scope', '$rootScope', '$state', '$window', '$sce', '$cookies', '$injector', 'Member', 'Auth', 'Session', 'activeProviderPromise', 'settingsPromise', 'growl', 'dialogs', 'CSRF', 'memberPromise', 'groups', '_t', + function ($scope, $rootScope, $state, $window, $sce, $cookies, $injector, Member, Auth, Session, activeProviderPromise, settingsPromise, growl, dialogs, CSRF, memberPromise, groups, _t) { /* PUBLIC SCOPE */ // API URL where the form will be posted @@ -111,7 +111,10 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _member_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // Angular-Bootstrap datepicker configuration for birthday $scope.datePicker = { diff --git a/app/frontend/src/javascript/controllers/profile.js b/app/frontend/src/javascript/controllers/profile.js index cba08dba6..5056c8a1a 100644 --- a/app/frontend/src/javascript/controllers/profile.js +++ b/app/frontend/src/javascript/controllers/profile.js @@ -203,6 +203,14 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo }); }; + /** + * Hide the new account messages. + * If hidden, the page will be used only to complete the current user's profile. + */ + $scope.hideNewAccountConfirmation = function () { + return !$scope.activeProvider.previous_provider || $scope.activeProvider.previous_provider.id === $scope.activeProvider.id; + }; + /* PRIVATE SCOPE */ /** diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index b1f5540ba..a0e85c3a1 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -167,7 +167,7 @@ angular.module('application.router', ['ui.router']) resolve: { groups: ['Group', function (Group) { return Group.query().$promise; }], activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }], - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.logged.dashboard.projects', { @@ -915,7 +915,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.members_import', { @@ -956,7 +956,7 @@ angular.module('application.router', ['ui.router']) walletPromise: ['Wallet', '$stateParams', function (Wallet, $stateParams) { return Wallet.getWalletByUser({ user_id: $stateParams.id }).$promise; }], transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }], tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }], - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.admins_new', { @@ -968,7 +968,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.managers_new', { @@ -1061,7 +1061,7 @@ angular.module('application.router', ['ui.router']) "'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', 'twitter_analytics', " + "'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', 'confirmation_required', " + "'reminder_delay', 'visibility_yearly', 'visibility_others', 'wallet_module', 'trainings_module', " + - "'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', " + + "'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', 'address_required', " + "'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown']" }).$promise; }], diff --git a/app/frontend/templates/admin/settings/general.html b/app/frontend/templates/admin/settings/general.html index 454672502..6948ffaae 100644 --- a/app/frontend/templates/admin/settings/general.html +++ b/app/frontend/templates/admin/settings/general.html @@ -427,7 +427,7 @@

{{ 'app.admin.settings.address' }}

- {{ 'app.admin.settings.address_required_info' }} + {{ 'app.admin.settings.address_required_info_html' }}

-
+
@@ -34,19 +34,19 @@
-
-

{{ 'app.logged.profile_completion.new_on_this_platform' }}

+

{{ 'app.logged.profile_completion.new_on_this_platform' }}

{{ 'app.logged.profile_completion.please_fill_the_following_form'}}.

{{ 'app.logged.profile_completion.some_data_may_have_already_been_provided_by_provider_and_cannot_be_modified' | translate:{NAME:activeProvider.name} }}.
{{ 'app.logged.profile_completion.then_click_on_' | translate }} {{ 'app.shared.buttons.confirm_changes' }} {{ 'app.logged.profile_completion._to_start_using_the_application' | translate }}.

@@ -145,14 +145,14 @@
-
diff --git a/app/frontend/templates/shared/_member_form.html b/app/frontend/templates/shared/_member_form.html index f277940d4..fbf336c10 100644 --- a/app/frontend/templates/shared/_member_form.html +++ b/app/frontend/templates/shared/_member_form.html @@ -224,7 +224,7 @@
- + @@ -234,7 +234,8 @@ class="form-control" id="user_address" ng-disabled="preventField['profile.address'] && user.invoicing_profile.address.address && !userForm['user[invoicing_profile_attributes][address_attributes][address]'].$dirty" - placeholder="{{ 'app.shared.user.address' | translate }}"/> + placeholder="{{ 'app.shared.user.address' | translate }}" + ng-required="addressRequired"/>
diff --git a/app/frontend/templates/shared/signupModal.html b/app/frontend/templates/shared/signupModal.html index b9f2639a8..a91c05f7d 100644 --- a/app/frontend/templates/shared/signupModal.html +++ b/app/frontend/templates/shared/signupModal.html @@ -213,6 +213,24 @@
+
+
+
+ + +
+ + + + {{ 'app.public.common.address_is_required' }} +
+
+
Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." address_is_required: "Address is required" captcha: "Captcha" captcha_info_html: "You can setup a protection against robots, to prevent them creating members accounts. This protection is using Google reCAPTCHA. Sign up for an API key pair to start using the captcha." diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index a98083288..d1110ac75 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1073,6 +1073,7 @@ fr: machines_sort_by: "l'ordre d'affichage des machines" fab_analytics: "Fab Analytics" phone_required: "téléphone requis" + address_required: "adresse requise" tracking_id: "l'ID de suivi" facebook_app_id: "l'App ID Facebook" twitter_analytics: "compte Twitter analytics" @@ -1110,7 +1111,7 @@ fr: phone_is_required: "Téléphone requis" phone_required_info: "Vous pouvez définir si le numéro de téléphone doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager." address: "Adresse" - address_required_info: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager. Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." + address_required_info_html: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager.
Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." address_is_required: "Adresse requise" captcha: "Captcha" captcha_info_html: "Vous pouvez mettre en place une protection contre les robots, pour les empêcher de créer des comptes membre. Cette protection utilise Google reCAPTCHA. Inscrivez vous pour obtenir une paire de clefs d'API afin d'utiliser le captcha." diff --git a/config/locales/app.public.en.yml b/config/locales/app.public.en.yml index ff55a8efd..f3c8b1244 100644 --- a/config/locales/app.public.en.yml +++ b/config/locales/app.public.en.yml @@ -84,6 +84,8 @@ en: birth_date_is_required: "Birth date is required." phone_number: "Phone number" phone_number_is_required: "Phone number is required." + address: "Address" + address_is_required: "Address is required" i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "I authorize FabLab users, registered on the site, to contact me" i_accept_to_receive_information_from_the_fablab: "I accept to receive information from the FabLab" i_ve_read_and_i_accept_: "I've read and I accept" diff --git a/config/locales/app.public.fr.yml b/config/locales/app.public.fr.yml index ab65878a2..0a6e258d9 100644 --- a/config/locales/app.public.fr.yml +++ b/config/locales/app.public.fr.yml @@ -84,6 +84,8 @@ fr: birth_date_is_required: "La date de naissance est requise." phone_number: "Numéro de téléphone" phone_number_is_required: "Le numéro de téléphone est requis." + address: "Adresse" + address_is_required: "L'adresse est requise" i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "J'autorise les utilisateurs du Fab Lab inscrits sur le site à me contacter" i_accept_to_receive_information_from_the_fablab: "J'accepte de recevoir des informations du Fab Lab" i_ve_read_and_i_accept_: "J'ai lu et j'accepte" diff --git a/lib/tasks/fablab/auth.rake b/lib/tasks/fablab/auth.rake index a555900ad..7d2c1d033 100644 --- a/lib/tasks/fablab/auth.rake +++ b/lib/tasks/fablab/auth.rake @@ -16,7 +16,7 @@ namespace :fablab do raise "FATAL ERROR: the provider '#{args.provider}' is already enabled" if AuthProvider.active.name == args.provider # disable previous provider - prev_prev = AuthProvider.find_by(status: 'previous') + prev_prev = AuthProvider.previous prev_prev&.update_attribute(:status, 'pending') AuthProvider.active.update_attribute(:status, 'previous') From 1749dea0e2ff86726d22a9657a277a75f4018104 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 23 Mar 2021 12:32:59 +0100 Subject: [PATCH 08/12] fix tests --- app/services/accounting_export_service.rb | 2 +- test/integration/availabilities/as_admin_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/accounting_export_service.rb b/app/services/accounting_export_service.rb index c86797b1a..81be782a7 100644 --- a/app/services/accounting_export_service.rb +++ b/app/services/accounting_export_service.rb @@ -33,7 +33,7 @@ class AccountingExportService invoices = Invoice.where('created_at >= ? AND created_at <= ?', start_date, end_date).order('created_at ASC') invoices = invoices.where('total > 0') unless export_zeros invoices.each do |i| - puts "processing invoice #{i.id}..." + puts "processing invoice #{i.id}..." unless Rails.env.test? content << generate_rows(i) end diff --git a/test/integration/availabilities/as_admin_test.rb b/test/integration/availabilities/as_admin_test.rb index 41df807fe..37b378768 100644 --- a/test/integration/availabilities/as_admin_test.rb +++ b/test/integration/availabilities/as_admin_test.rb @@ -124,8 +124,8 @@ module Availabilities 'expected end_at = start_at + 4 slots of 90 minutes' # Check the recurrence - assert_equal (availability[:start_at].to_date + 2.weeks), - availability[:end_date].to_date, + assert_equal (availability[:start_at].to_datetime + 2.weeks).to_date, + availability[:end_date].to_datetime.utc.to_date, 'expected end_date = start_at + 2 weeks' end end From 7001888437ae1c708874a2d34d69323b15053b33 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Wed, 24 Mar 2021 09:47:22 +0100 Subject: [PATCH 09/12] [bug] unable to run the setup script if sudoers belong to another group than sudo --- CHANGELOG.md | 1 + setup/setup.sh | 64 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee6ab44c1..2a8122c25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix a bug: recurring availabilities are not restricted to subscribers - Fix a bug: accounting exports may ignore some invoices for the first and last days - Fix a bug: accounting export caching is not working +- Fix a bug: unable to run the setup script if sudoers belong to another group than sudo - Fix a security issue: updated elliptic to 6.5.4 to fix [CVE-2020-28498](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498) - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash` - [TODO DEPLOY] `rails db:seed` diff --git a/setup/setup.sh b/setup/setup.sh index 17aad2a7c..d8c12fdc9 100755 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -26,12 +26,16 @@ welcome_message() system_requirements() { - if [ "$(whoami)" = "root" ]; then + if is_root; then echo "It is not recommended to run this script as root. As a normal user, elevation will be prompted if needed." read -rp "Continue anyway? (Y/n) " confirm &1) + if [ $? -eq 0 ]; then + echo "has_sudo__pass_set" + elif echo $prompt | grep -q '^sudo:'; then + echo "has_sudo__needs_pass" + else + echo "no_sudo" + fi +} + +elevate_cmd() +{ + local cmd=$@ + + HAS_SUDO=$(has_sudo) + + case "$HAS_SUDO" in + has_sudo__pass_set) + sudo $cmd + ;; + has_sudo__needs_pass) + echo "Please supply sudo password for the following command: sudo $cmd" + sudo $cmd + ;; + *) + echo "Please supply root password for the following command: su -c \"$cmd\"" + su -c "$cmd" + ;; + esac +} + read_email() { local email @@ -113,8 +157,8 @@ prepare_files() read -rp "Continue? (Y/n) " confirm Date: Wed, 24 Mar 2021 09:50:22 +0100 Subject: [PATCH 10/12] improved setup script style --- setup/setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/setup.sh b/setup/setup.sh index d8c12fdc9..093e062af 100755 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -209,7 +209,7 @@ prepare_nginx() echo "Removing nginx..." yq -i eval 'del(.services.nginx)' docker-compose.yml printf "The two following configurations are useful if you want to install Fab-manager behind a reverse proxy...\n" - read -rp "Do you want to map the Fab-manager's service to an external network? (Y/n) " confirm Date: Wed, 24 Mar 2021 11:04:59 +0100 Subject: [PATCH 11/12] improved upgrade script output --- setup/upgrade.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/upgrade.sh b/setup/upgrade.sh index ea8e8914f..47f21f4dc 100644 --- a/setup/upgrade.sh +++ b/setup/upgrade.sh @@ -87,7 +87,7 @@ add_environments() { for ENV in "${ENVIRONMENTS[@]}"; do if [[ "$ENV" =~ ^[A-Z0-9_]+=.*$ ]]; then - printf "Inserting variable %s...\n" "$ENV" + printf "\e[91m::\e[0m \e[1mInserting variable %s..\e[0m.\n" "$ENV" printf "# added on %s\n%s\n" "$(date +%Y-%m-%d\ %R)" "$ENV" >> "config/env" else echo "Ignoring invalid option: -e $ENV. Given value is not valid environment variable, please see https://huit.re/environment-doc" @@ -133,7 +133,7 @@ upgrade() BRANCH='master' if yq eval '.services.*.image | select(. == "sleede/fab-manager*")' docker-compose.yml | grep -q ':dev'; then BRANCH='dev'; fi for SCRIPT in "${SCRIPTS[@]}"; do - printf "Running script %s from branch %s...\n" "$SCRIPT" "$BRANCH" + printf "\e[91m::\e[0m \e[1mRunning script %s from branch %s...\e[0m\n" "$SCRIPT" "$BRANCH" if [[ "$YES_ALL" = "true" ]]; then \curl -sSL "https://raw.githubusercontent.com/sleede/fab-manager/$BRANCH/scripts/$SCRIPT.sh" | bash -s -- -y else @@ -143,7 +143,7 @@ upgrade() compile_assets docker-compose run --rm "$SERVICE" bundle exec rake db:migrate for COMMAND in "${COMMANDS[@]}"; do - printf "Running command %s...\n" "$COMMAND" + printf "\e[91m::\e[0m \e[1mRunning command %s...\e[0m\n" "$COMMAND" docker-compose run --rm "$SERVICE" bundle exec "$COMMAND" done docker-compose up -d @@ -152,7 +152,7 @@ upgrade() clean() { - echo "Current disk usage:" + echo -e "\e[91m::\e[0m \e[1mCurrent disk usage:\e[0m" df -h / [[ "$YES_ALL" = "true" ]] && confirm="y" || read -rp "Clean previous docker images? (y/N) " confirm Date: Wed, 24 Mar 2021 11:19:10 +0100 Subject: [PATCH 12/12] Version 4.7.6 --- CHANGELOG.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a8122c25..9d79ab451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog Fab-manager -## Next release +## v4.7.6 2021 March 24 - Ability to disable the trainings module - Ability to set the address as a mandatory field - The address is new requested when creating an account @@ -11,6 +11,7 @@ - Send pre-compressed assets to the browsers instead of the regular ones - Links created using "medium editor" opens in new tabs - Improved style of public plans page +- Improved the upgrade script - Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled - Fix a bug: select all plans for slot restriction (through the dedicated button) also selects the disabled plans - Fix a bug: recurring availabilities are not restricted to subscribers diff --git a/package.json b/package.json index a776ce1b8..81980e6eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "4.7.5", + "version": "4.7.6", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab",