1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-18 07:52:23 +01:00

Merge branch 'dev' for release 5.4.1

This commit is contained in:
Du Peng 2022-05-23 17:03:34 +02:00
commit 5edf883fd4
29 changed files with 154 additions and 42 deletions

View File

@ -2,6 +2,22 @@
## next deploy
## v5.4.1 2022 May 23
- Disable to clicking outside or pressing escape to close sign up modal
- Ability to disable colorize logging (#345)
- Detect assets compilation issue during the initial setup
- Fix a bug: when machines module disabled, Associated machines is still shown in trainings list
- Fix a bug: script mount-proof-of-identity-files unable to modify docker-compose.yml
- Fix a bug: Event reservation calendar encoding in mail
- Fix a bug: Missing of description of PlanCategory migration
- Fix a bug: Unable to create plans for all group
- Fix a bug: backPrevLocation button on Notification Center opens reset password page (#348)
- Fix a bug: compatibility with the new docker-compose CLI (#355)
- Fix a security issue: updated moment.js to 2.29.2. to fix [CVE-2022-24785](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24785)
- Fix a security issue: updated nokogiri to 1.13.6 to fix [CVE-2022-298240](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-298240)
- Fix a security issue: updated async to 2.6.4 to fix [CVE-2021-43138](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-43138)
## v5.4.0 2022 May 12
- Option to disable the 'machines' module

View File

@ -233,7 +233,7 @@ GEM
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.8)
nokogiri (1.13.4)
nokogiri (1.13.6)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
notify_with (0.0.2)

View File

@ -27,7 +27,7 @@ class API::PlansController < API::ApiController
partner = params[:plan][:partner_id].empty? ? nil : User.find(params[:plan][:partner_id])
plan = PlansService.create(type, partner, plan_params)
if plan.errors.keys.count.positive?
if plan.key?(:errors)
render json: plan.errors, status: :unprocessable_entity
else
render json: plan, status: :created

View File

@ -75,7 +75,11 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
// This is used to allow the user to navigate to the previous state
$transitions.onSuccess({ }, function (trans) {
$state.prevState = trans.$from().name;
$state.prevParams = trans.$from().params;
$state.prevParams = Object.fromEntries(
Object.keys(trans.$from().params).map(k => {
return [k, trans.$from().params[k].value()];
})
);
const path = trans.router.stateService.href(trans.$to(), {}, { absolute: true });
GTM.trackPage(path, trans.$to().name);

View File

@ -63,7 +63,7 @@ const ManagePlanCategoryComponent: React.FC<ManagePlanCategoryProps> = ({ catego
icon={<i className='fa fa-plus' />}
className="btn-warning"
onClick={toggleModal}>
{t('app.admin.create_plan_category.new_category')}
{t('app.admin.manage_plan_category.create_category.title')}
</FabButton>
);
case 'update':

View File

@ -181,16 +181,14 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
* @param content {Object}
*/
$scope.afterSubmit = function (content) {
if ((content.id == null) && (content.plan_ids == null)) {
if (content.plan_ids === null || content.plan_ids === undefined) {
return growl.error(_t('app.admin.plans.new.unable_to_create_the_subscription_please_try_again'));
} else {
growl.success(_t('app.admin.plans.new.successfully_created_subscriptions_dont_forget_to_redefine_prices'));
if (content.plan_ids != null) {
if (content.plan_ids.length > 1) {
return $state.go('app.admin.pricing');
} else {
if (content.id != null) {
return $state.go('app.admin.plans.edit', { id: content.id });
}
return $state.go('app.admin.plans.edit', { id: content.plan_ids[0] });
}
}
};

View File

@ -187,6 +187,8 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
// default tab: trainings list
$scope.tabs = { active: 0 };
$scope.enableMachinesModule = settingsPromise.machines_module === 'true';
/**
* In the trainings listing tab, return the stringified list of machines associated with the provided training
* @param training {Object} Training object, inherited from $resource

View File

@ -75,6 +75,8 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
} else {
return $uibModal.open({
templateUrl: '/shared/signupModal.html',
backdrop: 'static',
keyboard: false,
size: 'md',
resolve: {
settingsPromise: ['Setting', function (Setting) {
@ -189,6 +191,10 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
});
});
};
$scope.dismiss = function () {
$uibModalInstance.dismiss('cancel');
};
}]
}).result.finally(null).then(function (res) {
// when the account was created successfully, set the session to the newly created account

View File

@ -670,7 +670,7 @@ angular.module('application.router', ['ui.router'])
resolve: {
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display', 'machines_module']" }).$promise; }]
}
})
.state('app.admin.trainings_new', {

View File

@ -53,7 +53,7 @@
<thead>
<tr>
<th style="width:20%" translate>{{ 'app.admin.trainings.name' }}</th>
<th style="width:40%" translate>{{ 'app.admin.trainings.associated_machines' }}</th>
<th ng-if="enableMachinesModule" style="width:40%" translate>{{ 'app.admin.trainings.associated_machines' }}</th>
<th style="width:20%" translate>{{ 'app.admin.trainings.number_of_tickets' }}</th>
<th style="width:20%"></th>
</tr>
@ -61,7 +61,7 @@
<tbody>
<tr ng-repeat="training in trainings | filterDisabled:trainingFiltering" ng-class="{'disabled-line' : training.disabled && trainingFiltering === 'all'}">
<td>{{ training.name }}</td>
<td>{{ showMachines(training) }}</td>
<td ng-if="enableMachinesModule">{{ showMachines(training) }}</td>
<td>{{ training.nb_total_places }}</td>
<td>
<div class="buttons" ng-show="isAuthorized('admin')">

View File

@ -1,5 +1,6 @@
<div class="modal-header">
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
<i class="fa fa-times close-modal-button" ng-click="dismiss()"></i>
<h1 translate>{{ 'app.public.common.create_your_account' }}</h1>
</div>
<div class="">

View File

@ -54,7 +54,7 @@ class NotificationsMailer < NotifyWith::NotificationsMailer
end
def notify_member_create_reservation
attachments[@attached_object.ics_filename] = @attached_object.to_ics
attachments[@attached_object.ics_filename] = @attached_object.to_ics.encode(Encoding::ISO_8859_15)
mail(to: @recipient.email,
subject: t('notifications_mailer.notify_member_create_reservation.subject'),
template_name: 'notify_member_create_reservation')

View File

@ -6,5 +6,5 @@
# - plan_category
# - plan
class PlanCategory < ApplicationRecord
has_many :plan, dependent: :nullify
has_many :plans, dependent: :nullify
end

View File

@ -14,8 +14,10 @@ class PlansService
plan = type.constantize.new(params)
if plan.save
partner&.add_role :partner, plan
else
return { errors: plan.errors.full_messages }
end
plan
{ plan_ids: [plan.id] }
end
rescue PaymentGatewayError => e
{ errors: e.message }

View File

@ -69,6 +69,9 @@ module Fablab
Rails.application.config.paths['app/views'] << path
end
# disable ANSI color escape codes in active_record if NO_COLOR is defined.
config.colorize_logging = ENV['NO_COLOR'] ? false : true
FabManager.activate_plugins!
config.after_initialize do

View File

@ -1433,7 +1433,7 @@ fr:
change_group: "Changement de groupe"
change_group_info: "Une fois qu'un utilisateur a créé son compte, vous pouvez l'empêcher de changer de groupe. Dans ce cas, seuls les gestionnaires et les administrateurs pourront changer le groupe de l'utilisateur."
allow_group_change: "Autoriser le changement de groupe"
user_change_group: "les utilisateurs peuvent changer de groupe"
user_change_group: "changement de groupe"
wallet_module: "module porte-monnaie"
public_agenda_module: "module d'agenda public"
statistics_module: "module de statistiques"

View File

@ -0,0 +1,5 @@
class AddDescriptionToPlanCategory < ActiveRecord::Migration[5.2]
def change
add_column :plan_categories, :description, :text
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2022_05_09_105714) do
ActiveRecord::Schema.define(version: 2022_05_17_140916) do
# These are extensions that must be enabled in order to support this database
enable_extension "fuzzystrmatch"
@ -1021,8 +1021,8 @@ ActiveRecord::Schema.define(version: 2022_05_09_105714) do
t.boolean "is_allow_newsletter"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.string "mapped_from_sso"
t.datetime "validated_at"
t.string "mapped_from_sso"
t.index ["auth_token"], name: "index_users_on_auth_token"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true

View File

@ -269,6 +269,11 @@ See [Microsoft support](https://support.microsoft.com/en-us/kb/264372) for a lis
If set to `true`, and the application in started into a staging environment, this will enable the Crowdin In-context translation layer for the front-end application.
See [Crowdin documentation](https://support.crowdin.com/in-context-localization/) for more details about this.
Accordingly, `RAILS_LOCALE` and `APP_LOCALE` must be configured to `zu`.
<a name="NO_COLOR"></a>
NO_COLOR
If set to any value, this will set `config.colorize_logging` to `false`, disabling ANSI color codes when logging information.
<a name="open-projects-settings"></a>
## OpenLab settings
<a name="OPENLAB_BASE_URI"></a>

View File

@ -106,7 +106,7 @@ In order to remove ElasticSearch, you must **first** disable the statistics modu
Then, you can remove the `elasticsearch` service from the [docker-compose.yml](../setup/docker-compose.yml) file and restart the whole application:
```bash
docker-compose down && docker-compose up -d
docker compose down && docker compose up -d
```
Disabling ElasticSearch will save up to 800 Mb of memory.
@ -118,11 +118,11 @@ Before using any of these commands, you must first `cd` into the app directory.
- Read again the environment variables and restart
```bash
docker-compose down && docker-compose up -d
docker compose down && docker compose up -d
```
- Open a bash prompt inside the app container
```bash
docker-compose exec fabmanager bash
docker compose exec fabmanager bash
```
- Open the ruby console in the application
```bash
@ -130,11 +130,11 @@ docker-compose exec fabmanager bash
```
- Show services status
```bash
docker-compose ps
docker compose ps
```
- Run a command and provide it environment variables
```bash
docker-compose run --rm -e VAR1=xxx -e VAR2=xxx fabmanager bundle exec rails my:command
docker compose run --rm -e VAR1=xxx -e VAR2=xxx fabmanager bundle exec rails my:command
```
<a name="update-fab-manager"></a>
## Update Fab-manager
@ -192,11 +192,11 @@ Then, you'll need to perform the upgrade with the following command:
2. Pull last docker images
`docker-compose pull`
`docker compose pull`
3. Stop the app
`docker-compose stop fabmanager`
`docker compose stop fabmanager`
4. Remove old assets
@ -204,7 +204,7 @@ Then, you'll need to perform the upgrade with the following command:
5. Compile new assets
`docker-compose run --rm fabmanager bundle exec rails assets:precompile`
`docker compose run --rm fabmanager bundle exec rails assets:precompile`
6. Run specific commands
@ -212,23 +212,23 @@ Then, you'll need to perform the upgrade with the following command:
are always specified in the [CHANGELOG](https://github.com/sleede/fab-manager/blob/master/CHANGELOG.md) and prefixed by **[TODO DEPLOY]**.
Those commands execute specific tasks and have to be run manually.
You must prefix the commands starting by `rails...` or `rake...` with: `docker-compose run --rm fabmanager bundle exec`.
You must prefix the commands starting by `rails...` or `rake...` with: `docker compose run --rm fabmanager bundle exec`.
In any other cases, the other commands (like those invoking curl `\curl -sSL... | bash`) must not be prefixed.
You can also ignore commands only applicable to development environnement, which are prefixed by `(dev)` in the CHANGELOG.
7. Restart all containers
```bash
docker-compose down
docker-compose up -d
docker compose down
docker compose up -d
```
You can check that all containers are running with `docker-compose ps`.
You can check that all containers are running with `docker compose ps`.
<a name="upgrade-to-the-last-version"></a>
### Upgrade to the last version
It's the default behaviour as `docker-compose pull` command will fetch the latest versions of the docker images.
It's the default behaviour as `docker compose pull` command will fetch the latest versions of the docker images.
Be sure to run all the specific commands listed in the [CHANGELOG](https://github.com/sleede/fab-manager/blob/master/CHANGELOG.md) between your actual, and the new version in sequential order.
__Example:__ to update from v2.4.0 to v2.4.3, you will run the specific commands for the v2.4.1, v2.4.2 and v2.4.3.

View File

@ -1,6 +1,6 @@
{
"name": "fab-manager",
"version": "5.4.0",
"version": "5.4.1",
"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",

View File

@ -22,7 +22,10 @@ add_mount()
if [[ ! $(yq eval ".services.$SERVICE.volumes.[] | select (. == \"*payment_schedules\")" docker-compose.yml) ]]; then
# shellcheck disable=SC2016
# we don't want to expand ${PWD}
# change docker-compose.yml permissions for fix yq can't modify file issue
chmod 666 docker-compose.yml
yq -i eval ".services.$SERVICE.volumes += [\"\${PWD}/payment_schedules:/usr/src/app/payment_schedules\"]" docker-compose.yml
chmod 644 docker-compose.yml
fi
}

View File

@ -22,7 +22,10 @@ add_mount()
if [[ ! $(yq eval ".services.$SERVICE.volumes.[] | select (. == \"*proof_of_identity_files\")" docker-compose.yml) ]]; then
# shellcheck disable=SC2016
# we don't want to expand ${PWD}
# change docker-compose.yml permissions for fix yq can't modify file issue
chmod 666 docker-compose.yml
yq -i eval ".services.$SERVICE.volumes += [\"\${PWD}/proof_of_identity_files:/usr/src/app/proof_of_identity_files\"]" docker-compose.yml
chmod 644 docker-compose.yml
fi
}

View File

@ -1,3 +1,18 @@
#!/usr/bin/env bash
docker-compose exec -T postgres psql -Upostgres -c \\dFd | head -n -2 | tail -n +3 | awk '{ print gensub(/([a-z]+)_stem/,"\\1","g",$3); }'
docker-compose()
{
if ! docker compose version 1>/dev/null 2>/dev/null
then
if ! \docker-compose version 1>/dev/null 2>/dev/null
then
echo -e "\e[91m[ ❌ ] docker-compose was not found, exiting...\e[39m" && exit 1
else
\docker-compose "$@"
fi
else
docker compose "$@"
fi
}
docker-compose exec -T postgres psql -Upostgres -c \\dFd | head -n -2 | tail -n +3 | awk '{ print gensub(/([a-z]+)_stem/,"\\1","g",$3); }'

View File

@ -8,6 +8,21 @@ config() {
SERVICE="$(yq eval '.services.*.image | select(. == "sleede/fab-manager*") | path | .[-2]' docker-compose.yml)"
}
docker-compose()
{
if ! docker compose version 1>/dev/null 2>/dev/null
then
if ! \docker-compose version 1>/dev/null 2>/dev/null
then
echo -e "\e[91m[ ❌ ] docker-compose was not found, exiting...\e[39m" && exit 1
else
\docker-compose "$@"
fi
else
docker compose "$@"
fi
}
run()
{
config

View File

@ -45,7 +45,7 @@ system_requirements()
fi
done
fi
local _commands=("sudo" "curl" "sed" "openssl" "docker" "docker-compose" "systemctl")
local _commands=("sudo" "curl" "sed" "openssl" "docker" "systemctl")
for _command in "${_commands[@]}"; do
echo "detecting $_command..."
if ! command -v "$_command"
@ -54,9 +54,26 @@ system_requirements()
echo -e "\e[91m[ ❌ ] $_command was not found, exiting...\e[39m" && exit 1
fi
done
echo "detecting docker-compose..."
docker-compose version
printf "\e[92m[ ✔ ] All requirements successfully checked.\e[39m \n\n"
}
docker-compose()
{
if ! docker compose version 1>/dev/null 2>/dev/null
then
if ! \docker-compose version 1>/dev/null 2>/dev/null
then
echo -e "\e[91m[ ❌ ] docker-compose was not found, exiting...\e[39m" && exit 1
else
\docker-compose "$@"
fi
else
docker compose "$@"
fi
}
is_root()
{
return $(id -u)
@ -363,7 +380,9 @@ setup_assets_and_databases()
cd "$FABMANAGER_PATH" && docker-compose run --rm -e ADMIN_EMAIL="$EMAIL" -e ADMIN_PASSWORD="$PASSWORD" "$SERVICE" bundle exec rake db:seed # seed the database
# now build the assets
cd "$FABMANAGER_PATH" && docker-compose run --rm "$SERVICE" bundle exec rake assets:precompile
if ! docker-compose -f "$FABMANAGER_PATH/docker-compose.yml" run --rm "$SERVICE" bundle exec rake assets:precompile; then
echo -e "\e[91m[ ❌ ] someting went wrong while compiling the assets, exiting...\e[39m" && exit 1
fi
# and prepare elasticsearch
cd "$FABMANAGER_PATH" && docker-compose run --rm "$SERVICE" bundle exec rake fablab:es:build_stats

View File

@ -43,6 +43,21 @@ jq() {
docker run --rm -i -v "${PWD}:/data" imega/jq "$@"
}
docker-compose()
{
if ! docker compose version 1>/dev/null 2>/dev/null
then
if ! \docker-compose version 1>/dev/null 2>/dev/null
then
echo -e "\e[91m[ ❌ ] docker-compose was not found, exiting...\e[39m" && exit 1
else
\docker-compose "$@"
fi
else
docker compose "$@"
fi
}
# set $SERVICE and $YES_ALL
config()
{

View File

@ -41,7 +41,7 @@ class CreatePlanTest < ActionDispatch::IntegrationTest
# Check the created plan
plan = json_response(response.body)
assert_equal Plan.last.id, plan[:id]
assert_equal Plan.last.id, plan[:plan_ids][0]
assert_equal plans_count + 1, Plan.count
end
end

View File

@ -2930,9 +2930,9 @@ assert@^2.0.0:
util "^0.12.0"
async@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
dependencies:
lodash "^4.17.14"
@ -5517,9 +5517,9 @@ moment-timezone@0.5:
moment ">= 2.9.0"
moment@2.29, "moment@>= 2.9.0", "moment@>=2.8.0 <3.0.0":
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
version "2.29.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4"
integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==
ms@2.0.0:
version "2.0.0"