mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
(wip) move slot status request
This commit is contained in:
parent
986a663c40
commit
d0239a0e25
@ -29,6 +29,7 @@ class API::AvailabilitiesController < API::ApiController
|
||||
{ machines: machine_ids, spaces: params[:s], trainings: params[:t] },
|
||||
events: (params[:evt] && params[:evt] == 'true')
|
||||
)
|
||||
@user = current_user
|
||||
|
||||
@title_filter = { machine_ids: machine_ids.map(&:to_i) }
|
||||
@availabilities = filter_availabilites(@availabilities)
|
||||
|
@ -37,8 +37,6 @@ class Availability < ApplicationRecord
|
||||
scope :trainings, -> { includes(:trainings).where(available_type: 'training') }
|
||||
scope :spaces, -> { includes(:spaces).where(available_type: 'space') }
|
||||
|
||||
attr_accessor :is_reserved, :current_user_slots_reservations_ids, :current_user_pending_reservations_ids, :can_modify
|
||||
|
||||
validates :start_at, :end_at, presence: true
|
||||
validate :length_must_be_slot_multiple, unless: proc { end_at.blank? or start_at.blank? }
|
||||
validate :should_be_associated
|
||||
@ -114,6 +112,7 @@ class Availability < ApplicationRecord
|
||||
|
||||
# check if the reservations are complete?
|
||||
# if a nb_total_places hasn't been defined, then places are unlimited
|
||||
# @return [Boolean]
|
||||
def full?
|
||||
return false if nb_total_places.blank? && available_type != 'machines'
|
||||
|
||||
@ -124,6 +123,15 @@ class Availability < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array<Integer>] Collection of User's IDs
|
||||
def reserved_users
|
||||
slots.map(&:reserved_users).flatten
|
||||
end
|
||||
|
||||
def reserved?
|
||||
slots.map(&:reserved?).reduce(:&)
|
||||
end
|
||||
|
||||
# check availability don't have any reservation
|
||||
def empty?
|
||||
slots.map(&:empty?).reduce(:&)
|
||||
@ -140,7 +148,7 @@ class Availability < ApplicationRecord
|
||||
when 'machines'
|
||||
reservable.nil? ? machines.count : 1
|
||||
else
|
||||
raise TypeError
|
||||
raise TypeError, "unknown available type #{available_type} for availability #{id}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -16,29 +16,56 @@ class Slot < ApplicationRecord
|
||||
|
||||
attr_accessor :is_reserved, :machine, :space, :title, :can_modify, :current_user_slots_reservations_ids, :current_user_pending_reservations_ids
|
||||
|
||||
# @param reservable [Machine,Space,Training,Event,NilClass]
|
||||
# @return [Integer] the total number of reserved places
|
||||
def reserved_places(reservable = nil)
|
||||
if reservable.nil?
|
||||
places.pluck('reserved_places').reduce(:+)
|
||||
else
|
||||
places.detect { |p| p['reservable_type'] == reservable.class.name && p['reservable_id'] == reservable.id }['reserved_places']
|
||||
end
|
||||
end
|
||||
|
||||
# @param reservables [Array<Machine,Space,Training,Event>,NilClass]
|
||||
# @return [Array<Integer>] Collection of User's IDs
|
||||
def reserved_users(reservables = nil)
|
||||
if reservable.nil?
|
||||
places.pluck('user_ids').flatten
|
||||
else
|
||||
r_places = places.select do |p|
|
||||
reservables.any? { |r| r.class.name == p['reservable_type'] && r.id == p['reservable_id'] } # rubocop:disable Style/ClassEqualityComparison
|
||||
end
|
||||
r_places.pluck('user_ids').flatten
|
||||
end
|
||||
end
|
||||
|
||||
# @param reservable [Machine, Space, Training, Event, NilClass]
|
||||
# @return [Boolean] enough reservation to fill the whole slot?
|
||||
def full?(reservable = nil)
|
||||
availability_places = availability.available_places_per_slot(reservable)
|
||||
return false if availability_places.nil?
|
||||
|
||||
reserved_places = if reservable.nil?
|
||||
places.pluck('reserved_places').reduce(:+)
|
||||
else
|
||||
rp = places.detect do |p|
|
||||
p['reservable_type'] == reservable.class.name && p['reservable_id'] == reservable&.id
|
||||
end
|
||||
rp['reserved_places']
|
||||
end
|
||||
|
||||
reserved_places >= availability_places
|
||||
reserved_places(reservable) >= availability_places
|
||||
end
|
||||
|
||||
# @param reservable [Machine,Space,Training,Event,NilClass]
|
||||
# @return [Boolean] any reservation or none?
|
||||
def reserved?(reservable = nil)
|
||||
reserved_places(reservable).positive?
|
||||
end
|
||||
|
||||
# @param reservable [Machine,Space,Training,Event,NilClass]
|
||||
# @return [Boolean] no reservations at all?
|
||||
def empty?(reservable = nil)
|
||||
if reservable.nil?
|
||||
slots_reservations.where(canceled_at: nil).count.zero?
|
||||
else
|
||||
slots_reservations.includes(:reservation).where(canceled_at: nil).where('reservations.reservable': reservable).count.zero?
|
||||
end
|
||||
reserved_places(reservable).zero?
|
||||
end
|
||||
|
||||
# @param operator_role [String,NilClass] 'admin' | 'manager' | 'member'
|
||||
# @param user_id [Integer]
|
||||
# @param reservable [Machine,Space,Training,Event,NilClass]
|
||||
# @return [Boolean] the reservation on this slot can be modified?
|
||||
def modifiable?(operator_role, user_id, reservable = nil)
|
||||
%w[admin manager].include?(operator_role) || reserved_users([reservable]).include?(user_id)
|
||||
end
|
||||
|
||||
def duration
|
||||
|
@ -3,7 +3,7 @@
|
||||
# List all Availability's slots for the given resources
|
||||
class Availabilities::AvailabilitiesService
|
||||
# @param current_user [User]
|
||||
# @param level [String]
|
||||
# @param level [String] 'slot' | 'availability'
|
||||
def initialize(current_user, level = 'slot')
|
||||
@current_user = current_user
|
||||
@maximum_visibility = {
|
||||
@ -39,16 +39,16 @@ class Availabilities::AvailabilitiesService
|
||||
# @param window [Hash] the time window the look through: {start: xxx, end: xxx}
|
||||
# @option window [ActiveSupport::TimeWithZone] :start the beginning of the time window
|
||||
# @option window [ActiveSupport::TimeWithZone] :end the end of the time window
|
||||
def machines(machines, user, window)
|
||||
ma_availabilities = Availability.includes(:machines_availabilities, :availability_tags, :machines, :slots_reservations,
|
||||
slots: [:slots_reservations])
|
||||
# @param no_status [Boolean] should the availability/slot reservation status be computed?
|
||||
def machines(machines, user, window, no_status: false)
|
||||
ma_availabilities = Availability.includes(:machines_availabilities)
|
||||
.where('machines_availabilities.machine_id': machines.map(&:id))
|
||||
availabilities = availabilities(ma_availabilities, 'machines', user, window[:start], window[:end])
|
||||
|
||||
if @level == 'slot'
|
||||
availabilities.map(&:slots).flatten.map { |s| @service.slot_reserved_status(s, user, (machines & s.availability.machines)) }
|
||||
availabilities.map(&:slots).flatten.map { |s| no_status ? s : @service.slot_reserved_status(s, user, (machines & s.availability.machines)) }
|
||||
else
|
||||
availabilities.map { |a| @service.availability_reserved_status(a, user, (machines & a.machines)) }
|
||||
no_status ? availabilities : availabilities.map { |a| @service.availability_reserved_status(a, user, (machines & a.machines)) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -58,15 +58,16 @@ class Availabilities::AvailabilitiesService
|
||||
# @param window [Hash] the time window the look through: {start: xxx, end: xxx}
|
||||
# @option window [ActiveSupport::TimeWithZone] :start
|
||||
# @option window [ActiveSupport::TimeWithZone] :end
|
||||
def spaces(spaces, user, window)
|
||||
# @param no_status [Boolean] should the availability/slot reservation status be computed?
|
||||
def spaces(spaces, user, window, no_status: false)
|
||||
sp_availabilities = Availability.includes('spaces_availabilities')
|
||||
.where('spaces_availabilities.space_id': spaces.map(&:id))
|
||||
availabilities = availabilities(sp_availabilities, 'space', user, window[:start], window[:end])
|
||||
|
||||
if @level == 'slot'
|
||||
availabilities.map(&:slots).flatten.map { |s| @service.slot_reserved_status(s, user, (spaces & s.availability.spaces)) }
|
||||
availabilities.map(&:slots).flatten.map { |s| no_status ? s : @service.slot_reserved_status(s, user, (spaces & s.availability.spaces)) }
|
||||
else
|
||||
availabilities.map { |a| @service.availability_reserved_status(a, user, (spaces & a.spaces)) }
|
||||
no_status ? availabilities : availabilities.map { |a| @service.availability_reserved_status(a, user, (spaces & a.spaces)) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -76,15 +77,15 @@ class Availabilities::AvailabilitiesService
|
||||
# @param window [Hash] the time window the look through: {start: xxx, end: xxx}
|
||||
# @option window [ActiveSupport::TimeWithZone] :start
|
||||
# @option window [ActiveSupport::TimeWithZone] :end
|
||||
def trainings(trainings, user, window)
|
||||
def trainings(trainings, user, window, no_status: false)
|
||||
tr_availabilities = Availability.includes('trainings_availabilities')
|
||||
.where('trainings_availabilities.training_id': trainings.map(&:id))
|
||||
availabilities = availabilities(tr_availabilities, 'training', user, window[:start], window[:end])
|
||||
|
||||
if @level == 'slot'
|
||||
availabilities.map(&:slots).flatten.map { |s| @service.slot_reserved_status(s, user, (trainings & s.availability.trainings)) }
|
||||
availabilities.map(&:slots).flatten.map { |s| no_status ? s : @service.slot_reserved_status(s, user, (trainings & s.availability.trainings)) }
|
||||
else
|
||||
availabilities.map { |a| @service.availability_reserved_status(a, user, (trainings & a.trainings)) }
|
||||
no_status ? availabilities : availabilities.map { |a| @service.availability_reserved_status(a, user, (trainings & a.trainings)) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -94,18 +95,18 @@ class Availabilities::AvailabilitiesService
|
||||
# @param window [Hash] the time window the look through: {start: xxx, end: xxx}
|
||||
# @option window [ActiveSupport::TimeWithZone] :start
|
||||
# @option window [ActiveSupport::TimeWithZone] :end
|
||||
def events(events, user, window)
|
||||
def events(events, user, window, no_status: false)
|
||||
ev_availabilities = Availability.includes('event').where('events.id': events.map(&:id))
|
||||
availabilities = availabilities(ev_availabilities, 'event', user, window[:start], window[:end])
|
||||
|
||||
if @level == 'slot'
|
||||
availabilities.map(&:slots).flatten.map { |s| @service.slot_reserved_status(s, user, [s.availability.event]) }
|
||||
availabilities.map(&:slots).flatten.map { |s| no_status ? s : @service.slot_reserved_status(s, user, [s.availability.event]) }
|
||||
else
|
||||
availabilities.map { |a| @service.availability_reserved_status(a, user, [a.event]) }
|
||||
no_status ? availabilities : availabilities.map { |a| @service.availability_reserved_status(a, user, [a.event]) }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
protected
|
||||
|
||||
# @param user [User]
|
||||
def subscription_year?(user)
|
||||
@ -131,7 +132,7 @@ class Availabilities::AvailabilitiesService
|
||||
# 1) an admin (he can see all availabilities from 1 month ago to anytime in the future)
|
||||
if @current_user&.admin? || @current_user&.manager?
|
||||
window_start = [range_start, 1.month.ago].max
|
||||
availabilities.includes(:tags, :plans, :slots)
|
||||
availabilities.includes(:tags, :slots)
|
||||
.joins(:slots)
|
||||
.where('availabilities.start_at <= ? AND availabilities.end_at >= ? AND available_type = ?', range_end, window_start, type)
|
||||
.where('slots.start_at > ? AND slots.end_at < ?', window_start, range_end)
|
||||
@ -143,7 +144,7 @@ class Availabilities::AvailabilitiesService
|
||||
end_at = @maximum_visibility[:year] if show_more_trainings?(user) && type == 'training'
|
||||
window_end = [end_at, range_end].min
|
||||
window_start = [range_start, @minimum_visibility].max
|
||||
availabilities.includes(:tags, :plans, :slots)
|
||||
availabilities.includes(:tags, :slots)
|
||||
.joins(:slots)
|
||||
.where('availabilities.start_at <= ? AND availabilities.end_at >= ? AND available_type = ?', window_end, window_start, type)
|
||||
.where('slots.start_at > ? AND slots.end_at < ?', window_start, window_end)
|
||||
|
@ -11,10 +11,18 @@ class Availabilities::PublicAvailabilitiesService
|
||||
level = in_same_day(window[:start], window[:end]) ? 'slot' : 'availability'
|
||||
service = Availabilities::AvailabilitiesService.new(@current_user, level)
|
||||
|
||||
machines_slots = Setting.get('machines_module') ? service.machines(Machine.where(id: ids[:machines]), @current_user, window) : []
|
||||
spaces_slots = Setting.get('spaces_module') ? service.spaces(Space.where(id: ids[:spaces]), @current_user, window) : []
|
||||
trainings_slots = Setting.get('trainings_module') ? service.trainings(Training.where(id: ids[:trainings]), @current_user, window) : []
|
||||
events_slots = events ? service.events(Event.all, @current_user, window) : []
|
||||
machines_slots = if Setting.get('machines_module')
|
||||
service.machines(Machine.where(id: ids[:machines]), @current_user, window, no_status: true)
|
||||
else
|
||||
[]
|
||||
end
|
||||
spaces_slots = Setting.get('spaces_module') ? service.spaces(Space.where(id: ids[:spaces]), @current_user, window, no_status: true) : []
|
||||
trainings_slots = if Setting.get('trainings_module')
|
||||
service.trainings(Training.where(id: ids[:trainings]), @current_user, window, no_status: true)
|
||||
else
|
||||
[]
|
||||
end
|
||||
events_slots = events ? service.events(Event.all, @current_user, window, no_status: true) : []
|
||||
|
||||
[].concat(trainings_slots).concat(events_slots).concat(machines_slots).concat(spaces_slots)
|
||||
end
|
||||
|
@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# TODO, remove this
|
||||
# Provides helper methods checking reservation status of any availabilities
|
||||
class Availabilities::StatusService
|
||||
# @param current_user_role [String]
|
||||
@ -22,7 +22,7 @@ class Availabilities::StatusService
|
||||
|
||||
places = places(slot, reservables)
|
||||
is_reserved = places.any? { |p| p['reserved_places'].positive? }
|
||||
is_reserved_by_user = is_reserved && places.select { |p| p['user_ids'].include?(user.id) }.length.positive?
|
||||
is_reserved_by_user = is_reserved && user && places.select { |p| p['user_ids'].include?(user.id) }.length.positive?
|
||||
slot.is_reserved = is_reserved
|
||||
slot.title = slot_title(slot, is_reserved, is_reserved_by_user, reservables)
|
||||
slot.can_modify = true if %w[admin manager].include?(@current_user_role) || is_reserved
|
||||
|
37
app/services/slots/title_service.rb
Normal file
37
app/services/slots/title_service.rb
Normal file
@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Build the title of the provided slot
|
||||
class Slots::TitleService
|
||||
def initialize(operator_role, user)
|
||||
@user = user
|
||||
@show_name = (%w[admin manager].include?(operator_role) || (operator_role && Setting.get('display_name_enable')))
|
||||
end
|
||||
|
||||
# @param slot [Slot]
|
||||
# @param reservables [Array<Machine, Space, Training, Event>]
|
||||
def slot_title(slot, reservables)
|
||||
is_reserved = slot.reserved?
|
||||
is_reserved_by_user = slot.reserved_users(reservables).include?(@user.id)
|
||||
|
||||
name = reservables.map(&:name).join(', ')
|
||||
if !is_reserved && !is_reserved_by_user
|
||||
name
|
||||
elsif is_reserved && !is_reserved_by_user
|
||||
"#{name} #{@show_name ? "- #{Slots::TitleService.slot_users_names(slot, reservables)}" : ''}"
|
||||
else
|
||||
"#{name} - #{I18n.t('availabilities.i_ve_reserved')}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @param slot [Slot]
|
||||
# @param reservables [Array<Machine, Space, Training, Event>]
|
||||
# @return [String]
|
||||
def slot_users_names(slot, reservables)
|
||||
user_ids = slot.reserved_users(reservables)
|
||||
User.where(id: user_ids).includes(:profile)
|
||||
.map { |u| u&.profile&.full_name || I18n.t('availabilities.deleted_user') }
|
||||
.join(', ')
|
||||
end
|
||||
end
|
@ -1,16 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.slot_id slot.id
|
||||
json.can_modify slot.can_modify
|
||||
json.title slot.title
|
||||
json.can_modify slot.modifiable?(operator_role, @user.id, reservable)
|
||||
json.title Slots::TitleService.new(operator_role, @user).slot_title(slot, [reservable])
|
||||
json.start slot.start_at.iso8601
|
||||
json.end slot.end_at.iso8601
|
||||
json.is_reserved slot.is_reserved
|
||||
json.is_reserved slot.reserved?(reservable)
|
||||
json.is_completed slot.full?(reservable)
|
||||
json.backgroundColor 'white'
|
||||
|
||||
json.availability_id slot.availability_id
|
||||
json.slots_reservations_ids slot.current_user_slots_reservations_ids
|
||||
json.slots_reservations_ids slot.current_user_slots_reservations_ids #TODO, move this out of attr_accessor
|
||||
|
||||
json.tag_ids slot.availability.tag_ids
|
||||
json.tags slot.availability.tags do |t|
|
||||
|
@ -21,9 +21,9 @@ json.array!(@availabilities) do |availability|
|
||||
end
|
||||
|
||||
json.is_completed availability.full?
|
||||
json.is_reserved availability.is_reserved
|
||||
json.is_reserved availability.reserved?
|
||||
json.borderColor availability_border_color(availability)
|
||||
if availability.is_reserved && !availability.current_user_slots_reservations_ids.empty?
|
||||
if availability.reserved? && !@user.nil? && availability.reserved_users.include?(@user.id)
|
||||
json.title "#{availability.title}' - #{t('trainings.i_ve_reserved')}"
|
||||
elsif availability.full?
|
||||
json.title "#{availability.title} - #{t('trainings.completed')}"
|
||||
@ -38,7 +38,7 @@ json.array!(@availabilities) do |availability|
|
||||
json.id t.id
|
||||
json.name t.name
|
||||
end
|
||||
json.is_reserved availability.is_reserved
|
||||
json.is_reserved availability.reserved?
|
||||
json.is_completed availability.full?
|
||||
case availability.availability.available_type
|
||||
when 'machines'
|
||||
|
18
db/schema.rb
18
db/schema.rb
@ -19,8 +19,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
enable_extension "unaccent"
|
||||
|
||||
create_table "abuses", id: :serial, force: :cascade do |t|
|
||||
t.string "signaled_type"
|
||||
t.integer "signaled_id"
|
||||
t.string "signaled_type"
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "email"
|
||||
@ -68,8 +68,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
t.string "locality"
|
||||
t.string "country"
|
||||
t.string "postal_code"
|
||||
t.string "placeable_type"
|
||||
t.integer "placeable_id"
|
||||
t.string "placeable_type"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@ -93,8 +93,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
end
|
||||
|
||||
create_table "assets", id: :serial, force: :cascade do |t|
|
||||
t.string "viewable_type"
|
||||
t.integer "viewable_id"
|
||||
t.string "viewable_type"
|
||||
t.string "attachment"
|
||||
t.string "type"
|
||||
t.datetime "created_at"
|
||||
@ -281,8 +281,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
end
|
||||
|
||||
create_table "credits", id: :serial, force: :cascade do |t|
|
||||
t.string "creditable_type"
|
||||
t.integer "creditable_id"
|
||||
t.string "creditable_type"
|
||||
t.integer "plan_id"
|
||||
t.integer "hours"
|
||||
t.datetime "created_at"
|
||||
@ -524,15 +524,15 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
|
||||
create_table "notifications", id: :serial, force: :cascade do |t|
|
||||
t.integer "receiver_id"
|
||||
t.string "attached_object_type"
|
||||
t.integer "attached_object_id"
|
||||
t.string "attached_object_type"
|
||||
t.integer "notification_type_id"
|
||||
t.boolean "is_read", default: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "receiver_type"
|
||||
t.boolean "is_send", default: false
|
||||
t.jsonb "meta_data", default: "{}"
|
||||
t.jsonb "meta_data", default: {}
|
||||
t.index ["notification_type_id"], name: "index_notifications_on_notification_type_id"
|
||||
t.index ["receiver_id"], name: "index_notifications_on_receiver_id"
|
||||
end
|
||||
@ -772,8 +772,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
create_table "prices", id: :serial, force: :cascade do |t|
|
||||
t.integer "group_id"
|
||||
t.integer "plan_id"
|
||||
t.string "priceable_type"
|
||||
t.integer "priceable_id"
|
||||
t.string "priceable_type"
|
||||
t.integer "amount"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@ -976,8 +976,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
t.text "message"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "reservable_type"
|
||||
t.integer "reservable_id"
|
||||
t.string "reservable_type"
|
||||
t.integer "nb_reserve_places"
|
||||
t.integer "statistic_profile_id"
|
||||
t.index ["reservable_type", "reservable_id"], name: "index_reservations_on_reservable_type_and_reservable_id"
|
||||
@ -986,8 +986,8 @@ ActiveRecord::Schema.define(version: 2023_01_31_104958) do
|
||||
|
||||
create_table "roles", id: :serial, force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "resource_type"
|
||||
t.integer "resource_id"
|
||||
t.string "resource_type"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
|
||||
|
@ -32,7 +32,7 @@ Especially, if you have an automatic redirection (e.g. from example.org to examp
|
||||
Once you have reconfigured these variables, please switch back the active authentication provider to FabManager, restart the application, then delete the OIDC provider you configured and re-create a new one for the new settings to be used.
|
||||
|
||||
```
|
||||
Unable to decode ID token
|
||||
JSON::JWK::Set::KidNotFound (JSON::JWK::Set::KidNotFound)
|
||||
```
|
||||
This issue may occur if the ID Token signature algorithm is not set to `RSxxx` on your IDP.
|
||||
Especially, this is not the default option when using LemonLDAP::NG, which uses `HSxxx` as the default algorithm, but you can configure it in `OpenID Connect Relaying Parties` > `my-fab-manager` > `Options` > `Security` > `ID Token signature algorithm`.
|
||||
|
Loading…
Reference in New Issue
Block a user