diff --git a/lib/NGCP/Panel/Controller/Callflow.pm b/lib/NGCP/Panel/Controller/Callflow.pm index a88ce608f8..abf7dfe010 100644 --- a/lib/NGCP/Panel/Controller/Callflow.pm +++ b/lib/NGCP/Panel/Controller/Callflow.pm @@ -9,6 +9,7 @@ use NGCP::Panel::Utils::Navigation; use NGCP::Panel::Utils::Message; use HTML::Entities; +use MIME::Base64 qw(encode_base64url decode_base64url); sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { my ($self, $c) = @_; @@ -62,6 +63,13 @@ sub ajax :Chained('root') :PathPart('ajax') :Args(0) { $c, $calls_rs_cb, $c->stash->{capture_dt_columns}, + sub { + my $item = shift; + my %result; + $result{call_id} = $item->call_id =~ s/(_b2b-1|_pbx-1)+$//r; + $result{call_id_url} = encode_base64url($result{call_id}); + return %result; + }, ); $c->detach( $c->view("JSON") ); } @@ -69,9 +77,9 @@ sub ajax :Chained('root') :PathPart('ajax') :Args(0) { sub callflow_base :Chained('root') :PathPart('') :CaptureArgs(1) { my ($self, $c, $callid) = @_; - my $decoder = URI::Encode->new; - $c->stash->{callid} = $decoder->decode($callid) =~ s/_b2b-1$//r; - $c->stash->{callid} = $decoder->decode($callid) =~ s/_pbx-1$//r; + $c->stash->{callid} = decode_base64url($callid) + =~ s/(_b2b-1|_pbx-1)+$//r + =~ s/[^[:print:]]+//gr; # remove non-printable chars to be sure for db-operation } sub get_pcap :Chained('callflow_base') :PathPart('pcap') :Args(0) { diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 153538fbbc..8c6fd0300e 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -2,10 +2,13 @@ package NGCP::Panel::Controller::Subscriber; use NGCP::Panel::Utils::Generic qw(:all); use Sipwise::Base; use parent 'Catalyst::Controller'; + use HTML::Entities; use JSON qw(decode_json encode_json); use URI::Escape qw(uri_unescape); use Data::Dumper; +use MIME::Base64 qw(encode_base64url decode_base64url); + use NGCP::Panel::Utils::Navigation; use NGCP::Panel::Utils::Contract; use NGCP::Panel::Utils::Subscriber; @@ -3239,6 +3242,7 @@ sub _process_calls_rows { } $data{duration} = (defined $result->duration ? sprintf("%.2f s", $result->duration) : ""); $data{total_customer_cost} = (defined $result->get_column('total_customer_cost') ? sprintf("%.2f", $result->get_column('total_customer_cost') / 100.0) : ""); + $data{call_id_url} = encode_base64url($resource->{call_id}); return %data; }, { 'total_row_func' => sub { @@ -3350,8 +3354,9 @@ sub ajax_captured_calls :Chained('master') :PathPart('callflow/ajax') :Args(0) { sub { my $item = shift; my %result; - $result{call_id} = $item->call_id =~ s/(_b2b-1|_pbx-1)+$//rg; + $result{call_id} = $item->call_id =~ s/(_b2b-1|_pbx-1)+$//r; # similar to Utils::CallList::process_cdr_item + $result{call_id_url} = encode_base64url($result{call_id}); return %result; } ); @@ -4126,8 +4131,9 @@ sub callflow_base :Chained('base') :PathPart('callflow') :CaptureArgs(1) :Does(A $c->detach('/denied_page') unless($c->config->{features}->{callflow}); - my $decoder = URI::Encode->new; - $c->stash->{callid} = $decoder->decode($callid); + $c->stash->{callid} = decode_base64url($callid) + =~ s/(_b2b-1|_pbx-1)+$//r + =~ s/[^[:print:]]+//gr; # remove non-printable chars to be sure for db-operation } sub get_pcap :Chained('callflow_base') :PathPart('pcap') :Args(0) { diff --git a/share/templates/callflow/list.tt b/share/templates/callflow/list.tt index 764f7ea6a9..8f08d96b3d 100644 --- a/share/templates/callflow/list.tt +++ b/share/templates/callflow/list.tt @@ -15,7 +15,7 @@ helper.ajax_uri = c.uri_for('/callflow/ajax'); helper.dt_buttons = [ - { name = c.loc('Call Flow'), uri = "/callflow/'+encodeURIComponent(full.call_id)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, + { name = c.loc('Call Flow'), uri = "/callflow/'+encodeURIComponent(full.call_id_url)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, ]; PROCESS 'helpers/datatables.tt'; diff --git a/share/templates/subscriber/calllist.tt b/share/templates/subscriber/calllist.tt index 3e194781b8..07a1baf87a 100644 --- a/share/templates/subscriber/calllist.tt +++ b/share/templates/subscriber/calllist.tt @@ -58,7 +58,7 @@ function changeCalllist(selection) { IF (c.user.roles == "admin" || c.user.roles == "reseller"); IF c.config.features.callflow; helper.dt_buttons = [ - { name = c.loc('Call Flow'), uri = "/callflow/'+encodeURIComponent(full.call_id)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, + { name = c.loc('Call Flow'), uri = "/callflow/'+encodeURIComponent(full.call_id_url)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, ]; END; details_button = { name = c.loc('Call Details'), uri = "javascript:showCallDetails(\\''+encodeURIComponent(full.id)+'\\');void(0);" , class = 'btn-small btn-primary', icon = 'icon-edit' }; diff --git a/share/templates/subscriber/master.tt b/share/templates/subscriber/master.tt index 0dd85df5b3..3fb12ec210 100644 --- a/share/templates/subscriber/master.tt +++ b/share/templates/subscriber/master.tt @@ -277,7 +277,7 @@ function process_pbx_items(moveId,direction){ helper.ajax_uri = c.uri_for_action('/subscriber/ajax_captured_calls', [c.req.captures.0]); helper.dt_buttons = [ - { name = c.loc('Call Flow'), uri = "callflow/'+encodeURIComponent(full.call_id)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, + { name = c.loc('Call Flow'), uri = "callflow/'+encodeURIComponent(full.call_id_url)+'/callmap", class = 'btn-small btn-primary', icon = 'icon-random' }, ];