diff --git a/README.md b/README.md index 55806048..49355f72 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Installation information can be found on the [wiki](https://github.com/magicbug/ Cloudlog has two support systems for code issues use Github issues, however if you have general issues with setting up your server please use our general discussion forum [https://github.com/magicbug/Cloudlog/discussions](https://github.com/magicbug/Cloudlog/discussions). +## Security Vulnerabilities +If you discover a security vulnerability within Cloudlog, please send an e-mail to Peter Goodhall, 2M0SQL via [peter@magicbug.co.uk](mailto:peter@magicbug.co.uk). All security vulnerabilities will be promptly addressed. ## Want Cloudlog Hosting? diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..8c420770 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +## Reporting a Vulnerability + +If you discover a security vulnerability within Cloudlog, please send an e-mail to Peter Goodhall, 2M0SQL via [peter@magicbug.co.uk](mailto:peter@magicbug.co.uk). + +All security vulnerabilities will be promptly addressed. diff --git a/application/controllers/Awards.php b/application/controllers/Awards.php index e37220f3..4fa7d2ec 100644 --- a/application/controllers/Awards.php +++ b/application/controllers/Awards.php @@ -195,6 +195,14 @@ class Awards extends CI_Controller { $data['results'] = $this->logbook_model->qso_details($searchphrase, $band, $mode, $type); + // This is done because we have two different ways to get dxcc info in Cloudlog. Once is using the name (in awards), and the other one is using the ADIF DXCC. + // We replace the values to make it look a bit nicer + if ($type == 'DXCC2') { + $type = 'DXCC'; + $dxccname = $this->logbook_model->get_entity($searchphrase); + $searchphrase = $dxccname['name']; + } + // Render Page $data['page_title'] = "Log View - " . $type; $data['filter'] = $type . " " . $searchphrase . " and band ".$band . " and mode ".$mode; @@ -274,7 +282,10 @@ class Awards extends CI_Controller { public function was() { $this->load->model('was'); + $this->load->model('modes'); + $data['worked_bands'] = $this->was->get_worked_bands(); + $data['modes'] = $this->modes->active(); // Used in the view for mode select if ($this->input->post('band') != NULL) { // Band is not set when page first loads. if ($this->input->post('band') == 'All') { // Did the user specify a band? If not, use all bands @@ -297,6 +308,7 @@ class Awards extends CI_Controller { $postdata['confirmed'] = $this->input->post('confirmed'); $postdata['notworked'] = $this->input->post('notworked'); $postdata['band'] = $this->input->post('band'); + $postdata['mode'] = $this->input->post('mode'); } else { // Setting default values at first load of page $postdata['lotw'] = 1; @@ -305,10 +317,11 @@ class Awards extends CI_Controller { $postdata['confirmed'] = 1; $postdata['notworked'] = 1; $postdata['band'] = 'All'; + $postdata['mode'] = 'All'; } $data['was_array'] = $this->was->get_was_array($bands, $postdata); - $data['was_summary'] = $this->was->get_was_summary($bands); + $data['was_summary'] = $this->was->get_was_summary($data['worked_bands']); // Render Page $data['page_title'] = "Awards - WAS (Worked All States)"; @@ -472,24 +485,23 @@ class Awards extends CI_Controller { /* function was_map - This displays the WAS map and requires the $band_type + This displays the WAS map and requires the $band_type and $mode_type */ - public function was_map($band_type) { + public function was_map($band_type, $mode_type) { $this->load->model('was'); - $data['worked_bands'] = $this->was->get_worked_bands(); + + $data['mode'] = $mode_type; $bands[] = $band_type; - $data['bands'] = $bands; // Used for displaying selected band(s) in the table in the view - $postdata['lotw'] = 1; $postdata['qsl'] = 1; $postdata['worked'] = 1; $postdata['confirmed'] = 1; $postdata['notworked'] = 1; $postdata['band'] = $band_type; - + $postdata['mode'] = $mode_type; $data['was_array'] = $this->was->get_was_array($bands, $postdata); diff --git a/application/controllers/Lookup.php b/application/controllers/Lookup.php index e2247d16..587fb7da 100644 --- a/application/controllers/Lookup.php +++ b/application/controllers/Lookup.php @@ -35,18 +35,18 @@ class Lookup extends CI_Controller { $data['bands'] = $this->lookup_model->get_Worked_Bands($station_id); - $queryinfo['type'] = xss_clean($this->input->post('type')); - $queryinfo['dxcc'] = xss_clean($this->input->post('dxcc')); - $queryinfo['was'] = xss_clean($this->input->post('was')); - $queryinfo['sota'] = xss_clean($this->input->post('sota')); - $queryinfo['grid'] = xss_clean($this->input->post('grid')); - $queryinfo['iota'] = xss_clean($this->input->post('iota')); - $queryinfo['cqz'] = xss_clean($this->input->post('cqz')); - $queryinfo['wwff'] = xss_clean($this->input->post('wwff')); - $queryinfo['station_id'] = $station_id; - $queryinfo['bands'] = $data['bands']; + $data['type'] = xss_clean($this->input->post('type')); + $data['dxcc'] = xss_clean($this->input->post('dxcc')); + $data['was'] = xss_clean($this->input->post('was')); + $data['sota'] = xss_clean($this->input->post('sota')); + $data['grid'] = xss_clean($this->input->post('grid')); + $data['iota'] = xss_clean($this->input->post('iota')); + $data['cqz'] = xss_clean($this->input->post('cqz')); + $data['wwff'] = xss_clean($this->input->post('wwff')); + $data['station_id'] = $station_id; + + $data['result'] = $this->lookup_model->getSearchResult($data); - $data['result'] = $this->lookup_model->getSearchResult($queryinfo); $this->load->view('lookup/result', $data); } diff --git a/application/controllers/Qslprint.php b/application/controllers/Qslprint.php index fc2f2c00..3de67e65 100644 --- a/application/controllers/Qslprint.php +++ b/application/controllers/Qslprint.php @@ -149,6 +149,22 @@ class QSLPrint extends CI_Controller { $data['station_id'] = $station_id; $this->load->view('qslprint/qslprint', $data); } + + public function open_qso_list() { + $callsign = $this->input->post('callsign'); + $this->load->model('qslprint_model'); + + $data['qsos'] = $this->qslprint_model->open_qso_list($this->security->xss_clean($callsign)); + $this->load->view('qslprint/qsolist', $data); + } + + public function add_qso_to_print_queue() { + $id = $this->input->post('id'); + $this->load->model('qslprint_model'); + + $this->qslprint_model->add_qso_to_print_queue($this->security->xss_clean($id)); + } + } /* End of file Qslprint.php */ diff --git a/application/libraries/Qra.php b/application/libraries/Qra.php index 8d38ed7f..7398151d 100644 --- a/application/libraries/Qra.php +++ b/application/libraries/Qra.php @@ -1,4 +1,4 @@ -config->item('table_name') . " thcv"; - $sql .= " where station_id = " . $station_id; + $sql .= " where station_id = " . $station_id . ' and col_cqz > 0'; if ($band == 'SAT') { $sql .= " and thcv.col_prop_mode ='" . $band . "'"; @@ -258,7 +258,7 @@ class CQ extends CI_Model{ function getSummaryByBandConfirmed($band, $station_id){ $sql = "SELECT count(distinct thcv.col_cqz) as count FROM " . $this->config->item('table_name') . " thcv"; - $sql .= " where station_id = " . $station_id; + $sql .= " where station_id = " . $station_id . ' and col_cqz > 0'; if ($band == 'SAT') { $sql .= " and thcv.col_prop_mode ='" . $band . "'"; diff --git a/application/models/Dxcc.php b/application/models/Dxcc.php index 5a8e712c..54112070 100644 --- a/application/models/Dxcc.php +++ b/application/models/Dxcc.php @@ -322,7 +322,7 @@ class DXCC extends CI_Model { from dxcc_entities"; if ($postdata['notworked'] == NULL) { - $sql .= " join (select col_dxcc from ".$this->config->item('table_name')." where station_id = $station_id"; + $sql .= " join (select col_dxcc from " . $this->config->item('table_name') . " where station_id = " . $station_id . " and col_dxcc > 0"; if ($postdata['band'] != 'All') { if ($postdata['band'] == 'SAT') { @@ -377,7 +377,7 @@ class DXCC extends CI_Model { $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; } - $sql .= " and not exists (select 1 from ".$this->config->item('table_name')." where station_id = $station_id and col_dxcc = thcv.col_dxcc"; + $sql .= " and not exists (select 1 from ".$this->config->item('table_name')." where station_id = $station_id and col_dxcc = thcv.col_dxcc and col_dxcc > 0"; if ($postdata['band'] != 'All') { if ($postdata['band'] == 'SAT') { @@ -530,7 +530,7 @@ class DXCC extends CI_Model { { $sql = "SELECT count(distinct thcv.col_dxcc) as count FROM " . $this->config->item('table_name') . " thcv"; - $sql .= " where station_id = " . $station_id; + $sql .= " where station_id = " . $station_id . " and col_dxcc > 0"; if ($band == 'SAT') { @@ -561,7 +561,7 @@ class DXCC extends CI_Model { $sql .= " and thcv.col_band ='" . $band . "'"; } - $sql .= " and (col_qsl_rcvd = 'Y' or col_lotw_qsl_rcvd = 'Y')"; + $sql .= " and (col_qsl_rcvd = 'Y' or col_lotw_qsl_rcvd = 'Y') and col_dxcc > 0"; $query = $this->db->query($sql); diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 7bdba991..a9649638 100755 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -244,6 +244,9 @@ class Logbook_model extends CI_Model { case 'DXCC': $this->db->where('COL_COUNTRY', $searchphrase); break; + case 'DXCC2': + $this->db->where('COL_DXCC', $searchphrase); + break; case 'IOTA': $this->db->where('COL_IOTA', $searchphrase); break; @@ -257,6 +260,13 @@ class Logbook_model extends CI_Model { $this->db->where('COL_STATE', $searchphrase); $this->db->where_in('COL_DXCC', ['291', '6', '110']); break; + case 'SOTA': + $this->db->where('COL_SOTA_REF', $searchphrase); + break; + case 'WWFF': + $this->db->where('COL_SIG', 'WWFF'); + $this->db->where('COL_SIG_INFO', $searchphrase); + break; } $this->db->where('station_id', $station_id); @@ -2099,7 +2109,14 @@ class Logbook_model extends CI_Model { if (preg_match('/(^KG4)[A-Z09]{3,}/', $call)) { // KG4/ and KG4 5 char calls are Guantanamo Bay. If 6 char, it is USA $call = "K"; - } + } elseif (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $call, $matches)) { + if ($matches[5][0] == '/MM') { + $row['adif'] = 0; + $row['entity'] = 'None'; + $row['cqz'] = 0; + return array($row['adif'], $row['entity'], $row['cqz']); + } + } $len = strlen($call); @@ -2144,7 +2161,16 @@ class Logbook_model extends CI_Model { if (preg_match('/(^KG4)[A-Z09]{3,}/', $call)) { // KG4/ and KG4 5 char calls are Guantanamo Bay. If 6 char, it is USA $call = "K"; - } + } elseif (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $call, $matches)) { + if ($matches[5][0] == '/MM') { + $row['adif'] = 0; + $row['entity'] = 'None'; + $row['cqz'] = 0; + $row['long'] = '0'; + $row['lat'] = '0'; + return $row; + } + } $len = strlen($call); diff --git a/application/models/Qslprint_model.php b/application/models/Qslprint_model.php index 354e2460..b32ef8b5 100644 --- a/application/models/Qslprint_model.php +++ b/application/models/Qslprint_model.php @@ -63,6 +63,28 @@ class Qslprint_model extends CI_Model { return true; } + + function add_qso_to_print_queue($id) { + $data = array( + 'COL_QSL_SENT' => "R", + ); + + $this->db->where("COL_PRIMARY_KEY", $id); + $this->db->update($this->config->item('table_name'), $data); + + return true; + } + + function open_qso_list($callsign) { + $this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id'); + $this->db->where('COL_CALL like "%'.$callsign.'%"'); + $this->db->where('coalesce(COL_QSL_SENT, "") not in ("R", "Q")'); + $this->db->order_by("COL_TIME_ON", "ASC"); + $query = $this->db->get($this->config->item('table_name')); + + return $query; + } + } ?> diff --git a/application/models/Was.php b/application/models/Was.php index c6e76394..0d98cdd3 100644 --- a/application/models/Was.php +++ b/application/models/Was.php @@ -87,14 +87,14 @@ class was extends CI_Model { if ($postdata['worked'] != NULL) { $wasBand = $this->getWasWorked($station_id, $band, $postdata); foreach ($wasBand as $line) { - $bandWas[$line->col_state][$band] = '
'; + $bandWas[$line->col_state][$band] = ''; $states[$line->col_state]['count']++; } } if ($postdata['confirmed'] != NULL) { $wasBand = $this->getWasConfirmed($station_id, $band, $postdata); foreach ($wasBand as $line) { - $bandWas[$line->col_state][$band] = ''; + $bandWas[$line->col_state][$band] = ''; $states[$line->col_state]['count']++; } } @@ -211,6 +211,10 @@ class was extends CI_Model { $sql = "SELECT distinct col_state FROM " . $this->config->item('table_name') . " thcv where station_id = " . $station_id; + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + $sql .= $this->addStateToQuery(); $sql .= $this->addBandToQuery($band); @@ -219,6 +223,10 @@ class was extends CI_Model { " where station_id = ". $station_id . " and col_state = thcv.col_state"; + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + $sql .= $this->addBandToQuery($band); $sql .= $this->addQslToQuery($postdata); @@ -240,6 +248,10 @@ class was extends CI_Model { $sql = "SELECT distinct col_state FROM " . $this->config->item('table_name') . " thcv where station_id = " . $station_id; + if ($postdata['mode'] != 'All') { + $sql .= " and (col_mode = '" . $postdata['mode'] . "' or col_submode = '" . $postdata['mode'] . "')"; + } + $sql .= $this->addStateToQuery(); $sql .= $this->addBandToQuery($band); diff --git a/application/views/awards/was/index.php b/application/views/awards/was/index.php index 5531b8f3..904346f8 100644 --- a/application/views/awards/was/index.php +++ b/application/views/awards/was/index.php @@ -5,7 +5,6 @@