Commit 457047ee authored by Cooper, Caleb's avatar Cooper, Caleb

Merge branch 'dev' into 'master'

Merge Request for version 1.3.7

See merge request !75
parents 16319b60 06729282
Pipeline #47208 passed with stages
in 1 minute and 1 second
/* Prevents highlighting of text, dragging of images, etc. */
*, *::after, *::before {
margin: 0;
padding: 0;
-webkit-user-select: none;
-webkit-user-drag: none;
-webkit-app-region: no-drag;
font-family: 'Montserrat', sans-serif;
}
div {
-webkit-user-select: none;
-webkit-user-drag: none;
-webkit-app-region: no-drag;
font-family: 'Montserrat', sans-serif;
}
/* Horizontal line formatting */
hr {
display: block;
margin-top: 0.15em;
margin-bottom: 0.15em;
}
/* For submission buttons */
input[type=submit] {
padding: 0;
border: none;
background: none;
font-size: 21px;
}
#MFAVerificationPage {
display: flex;
flex-direction: column;
height: 100vh;
justify-content: center;
align-items: center;
}
#MFAVerificationText {
text-align: center;
font-size: 15px;
margin-bottom: 15px;
margin-left: 12px;
margin-right: 12px;
}
#MFAVerificationButton {
align-self: center;
background-color: #007833;
border-radius: 8px;
width: 50vw;
height: 30vh;
text-align: center;
font-size: 30px;
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.2), 0 4px 8px 0 rgba(0,0,0,0.19);
}
#MFAVerificationButton:hover {
background-color: Gray;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Smart Card Verification</title>
<link rel="stylesheet" href="./MFAVerification.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<script src="./MFAVerification.js"></script>
</head>
<body>
<div id="MFAVerificationPage">
<div id="MFAVerificationText">
Please ensure that there is one smart card inserted before clicking 'Verify'
</div>
<span title="Click 'Verify' to see if the currently inserted smart card has an entry in the digest mapping.">
<input type="submit" value="Verify" style="color:white" id="MFAVerificationButton" onclick="MFAVerification()">
</span>
</div>
</body>
</html>
const electron = require('electron')
const execSync = require('child_process').execSync
const ipcRenderer = require('electron').ipcRenderer
//Checks if the Yubikey is locked and alerts the user accordingly
function MFAVerification() {
ipcRenderer.send('log', 'ORNL Toolbox: Submitted MFA verification request', 'info')
try { //Scan for active smart card slots for inserted smart cards
var cardCheck = execSync(`pkcs11-tool -T | grep "Slot"`, (error, stdout, stderr) => {})
cardCheck = cardCheck.toString()
} catch(error) {
error = error.toString()
if(error.includes("No slots")) {
alert('No smart card inserted')
ipcRenderer.send('log', 'ORNL Toolbox: No smart card inserted - request aborted', 'err')
return
} else {
alert(error)
ipcRenderer.send('log', 'ORNL Toolbox: Error checking for smart card - request aborted', 'err')
return
}
}
//Check for the number of smart card slots
var count = (cardCheck.match(/Slot/g) || []).length;
if(count > 1) { //More than one slot found
alert('Please ensure only one smart card is inserted')
ipcRenderer.send('log', 'ORNL Toolbox: More than one smart card inserted - request aborted', 'err')
return
} else if(count < 1) { //No slots found
alert('No smart card inserted')
ipcRenderer.send('log', 'ORNL Toolbox: No smart card inserted - request aborted', 'err')
return
} else {
ipcRenderer.send('log', 'ORNL Toolbox: 1 smart card found inserted', 'info')
}
try { //Check for entry in digest mapping file
var inDigest = execSync(`grep $(pkcs15-tool -r 1 --rfc4716 2>/dev/null | openssl x509 -noout -fingerprint -sha1 -inform pem | grep -Po '(?<==).*(?=$)') /etc/pam_pkcs11/digest_mapping`, (error, stdout, stderr) => {})
} catch(error) {
error = error.toString()
if(error.includes('unable to load certificate')) { //Extra safety for no smartcard inserted scenario
alert('No smart card inserted')
ipcRenderer.send('log', 'ORNL Toolbox: No smart card inserted - request aborted', 'err')
return
} else {
inDigest = ""
}
}
if(inDigest == "") { //Tell user the if the smart card has an entry or not
//Not in digest mapping
alert('Inserted smart card absent from diggest mapping and will not function')
ipcRenderer.send('log', 'ORNL Toolbox: Inserted smart card was not found in /etc/pam_pkcs11/digest_mapping', 'info')
} else {
//In digest mapping
alert('Inserted smart card present in digest mapping and should function unless locked')
ipcRenderer.send('log', 'ORNL Toolbox: Inserted smart card has an entry in /etc/pam_pkcs11/digest_mapping', 'info')
}
ipcRenderer.send('log', 'ORNL Toolbox: Completed MFA verification request', 'info')
}
......@@ -88,6 +88,12 @@ input[type=submit] {
background-color: White;
}
#badgeManagementHiddenbuttons {
width: 32vh;
height: 20vh;
padding: 4px 4px;
margin: 30px 30px;
}
.backContent {
display: flex;
......
......@@ -10,12 +10,15 @@
<script src="../miscjs/openURL.js"></script>
<script src="../miscjs/launchBomgar.js"></script>
<script src="../softwareManagement/openSoftware/openSoftware.js"></script>
<script src="../softwareManagement/softwareCheckpoint/softwareCheckpoint.js"></script>
<script src="../miscjs/menuFunctionCalls.js"></script>
<script src="./yubiBadgeCheckpoint/yubiBadgeCheckpoint.js"></script>
<script src="./badgeMinder/badgeInstallCheckpoint/badgeInstallCheckpoint.js"></script>
<script src="../fileSystemManagement/localDriveUsage/localDriveUsage.js"></script>
<script src="../fileSystemManagement/addPassphrase/addPassphrase.js"></script>
<script src="../fileSystemManagement/removePassphrase/removePassphrase.js"></script>
<script src="../fileSystemManagement/driveHealthCheck/driveHealthCheck.js"></script>
<script src="../fileSystemManagement/baobabCheckpoint/baobabCheckpoint.js"></script>
<script src="../miscjs/installedCheck.js"></script>
</head>
<body>
......@@ -36,7 +39,7 @@
</div>
<div class="content">
<span title="Opens an application page for changing Badge Minder settings.">
<div id="buttons" onclick="addWinMain('./badgeManagement/badgeMinder/badgeMinder.html', 'Badge Minder', 450, 360)"><font color="white">Badge Minder</font></div>
<div id="buttons" onclick="badgeInstallCheckpoint()"><font color="white">Badge Minder</font></div>
</span>
<span title="Opens an application page for checking if the inserted Yubikey is locked.">
<div id="buttons" onclick="yubiBadgeCheckpoint(0)"><font color="white">Yubikey Lock Checker</font></div>
......@@ -44,9 +47,16 @@
<span title="Opens an application page for changing the PIN on the inserted Yubikey.">
<div id="buttons" onclick="yubiBadgeCheckpoint(1)"><font color="white">Yubikey PIN Changer</font></div>
</span>
<span title="Opens an application page for verifying that a smart card is in the digest mapping file.">
<div id="buttons" onclick="addWinMain('./badgeManagement/MFAVerification/MFAVerification.html', 'Smart Card Verification', 225, 180)"><font color="white">Smart Card Verification</font></div>
</span>
<span title="Opens an application page for temporarily registering a smart card in the digest mapping file.">
<div id="buttons" onclick="addWinMain('./badgeManagement/tempMFARegistration/tempMFARegistration.html', 'Temporary Smart Card Registration', 225, 180)"><font color="white">Temporary Smart Card Registration</font></div>
</span>
<div id="badgeManagementHiddenbuttons"></div>
</div>
<span title="Opens an application page for submitting feedback regarding ORNL Toolbox.">
<div class="feedbackContainer" onclick="addWinMain('./feedback/feedback.html', 'Give Feedback', 500, 300)">
<div class="feedbackContainer" onclick="addWinMain('./feedback/feedback.html', 'Feedback', 500, 300)">
<div class="feedbackImage">
<img src="../images/comment-white-oval-bubble-shape.png" alt="White Chat Bubble">
</div>
......@@ -54,12 +64,13 @@
</div>
</span>
<span title="Opens an application page for seeking help regarding your system.">
<div class="helpContainer" onclick="addWinMain('./help/help.html', 'Email to Support', 500, 400)">
<div class="helpContainer" onclick="addWinMain('./help/help.html', 'Help', 500, 400)">
<div class="helpImage">
<img src="../images/help-web-button-white.png" alt="Question Mark">
</div>
<div class="helpText"><font color="white">Help</font></div>
</div>
</span>
</body>
</html>
//Loads the badgeManagement major page and closes minor windows
function badgeManWin() {
ipcRenderer.send('log', 'ORNL Toolbox: Opened Badge Management', 'info')
//Destroying any minor windows that were opened from the main window
ipcRenderer.send('close minor window')
// Change main window to badge management window
......
/* Prevents highlighting of text, dragging of images, etc. */
*, *::after, *::before {
margin: 0;
padding: 0;
-webkit-user-select: none;
-webkit-user-drag: none;
-webkit-app-region: no-drag;
font-family: 'Montserrat', sans-serif;
}
div {
-webkit-user-select: none;
-webkit-user-drag: none;
-webkit-app-region: no-drag;
font-family: 'Montserrat', sans-serif;
}
/* Horizontal line formatting */
hr {
display: block;
margin-top: 0.15em;
margin-bottom: 0.15em;
}
/* For submission buttons */
input[type=submit] {
padding: 0;
border: none;
background: none;
font-size: 21px;
}
#badgeInstallCheckpointPage {
display: flex;
height: 100vh;
flex-direction: column;
justify-content: center;
align-items: center;
}
#badgeInstallCheckpointText {
font-size: 16px;
text-align: center;
margin-bottom: 25px;
margin-left: 12px;
margin-right: 12px;
}
.badgeInstallCheckpointButtonsContent {
width: 100vw;
height: 10vh;
display: flex;
flex-direction: row;
justify-content: center;
}
.badgeInstallCheckpointButtons {
text-align: center;
align-items: center;
width: 22vw;
height: 18vh;
margin-right: 12.5px;
margin-left: 12.5px;
background-color: #007833 !important;
border-radius: 8px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2), 0 4px 8px 0 rgba(0,0,0,0.19);
color: White;
}
.badgeInstallCheckpointButtons:hover {
background-color: Gray !important;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Badge Minder Checkpoint</title>
<link rel="stylesheet" href="./badgeInstallCheckpoint.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<script src="../../../miscjs/addWindow.js"></script>
<script src="../badgeMinderClose.js"></script>
<script src="./badgeInstallCheckpointConfirm.js"></script>
</head>
<body>
<div id="badgeInstallCheckpointPage">
<div id="badgeInstallCheckpointText">
Gnome-Screensaver is not currently installed. Badge Minder requires
Gnome-Screensaver to function. Would you like to install it?
</div>
<div class="badgeInstallCheckpointButtonsContent">
<span title="Click 'Install' to install gnome-screensaver, which is required for Badge Minder">
<input type="submit" class="badgeInstallCheckpointButtons" value="Install" onclick="badgeInstallCheckpointConfirm()">
</span>
<span title="Click 'Close' to close this current window and decline the installation.">
<input type="submit" class="badgeInstallCheckpointButtons" value="Close" onclick="badgeMinderClose()">
</span>
</div>
</div>
</body>
</html>
function badgeInstallCheckpoint() {
if(!ipcRenderer) var ipcRenderer = require('electron').ipcRenderer
if(!execSync) var execSync = require('child_process').execSync
ipcRenderer.send('log', 'ORNL Toolbox: Submitted Badge Install Checkpoint request', 'info')
var os
try { //Detect OS
execSync('grep Ubuntu /etc/os-release')
os = "Ubuntu"
ipcRenderer.send('log', 'ORNL Toolbox: OS determined to be Ubuntu', 'info')
} catch(error) {
//"Ubuntu" not found in file
os = "RHEL"
ipcRenderer.send('log', 'ORNL Toolbox: OS determined to be RHEL', 'info')
}
try {
if(os == "Ubuntu") {
package = execSync(`apt -qq list --installed gnome-screensaver`)
} else {
package = execSync(`yum list installed gnome-screensaver | grep gnome-screensaver`)
}
} catch(error) {
error = error.toString()
if(os != "Ubuntu" && error.includes("No matching Packages to list")) {
package = ""
} else {
alert(error)
ipcRenderer.send('log', 'ORNL Toolbox: Failed while checking for gnome-screensaver - request aborted', 'err')
return
}
}
ipcRenderer.send('log', 'ORNL Toolbox: Completed Badge Install Checkpoint request', 'info')
if(package == "") {
addWinMain('./badgeManagement/badgeMinder/badgeInstallCheckpoint/badgeInstallCheckpoint.html', 'Badge Minder Checkpoint', 400, 175)
} else {
addWinMain('./badgeManagement/badgeMinder/badgeMinder.html', 'Badge Minder', 450, 360)
}
}
function badgeInstallCheckpointConfirm() {
if(!ipcRenderer) var ipcRenderer = require('electron').ipcRenderer
if(!execSync) var execSync = require('child_process').execSync
ipcRenderer.send('log', 'ORNL Toolbox: Submitted install request for gnome-screensaver', 'info')
var os
try { //Detect OS
execSync('grep Ubuntu /etc/os-release')
os = "Ubuntu"
ipcRenderer.send('log', 'ORNL Toolbox: OS determined to be Ubuntu', 'info')
} catch(error) {
//"Ubuntu" not found in file
os = "RHEL"
ipcRenderer.send('log', 'ORNL Toolbox: OS determined to be RHEL', 'info')
}
try { //Install gnome-screensaver
if(os == "Ubuntu") {
execSync(`pkexec apt install gnome-screensaver`)
} else {
execSync(`pkexec yum -y install gnome-screensaver`)
}
} catch(error) {
error = error.toString()
if(error.includes("Request dismissed")) {
ipcRenderer.send('log', 'ORNL Toolbox: Request canceled by user', 'err')
badgeMinderClose()
return
} else {
ipcRenderer.send('log', 'ORNL Toolbox: Failed to install gnome-screensaver - request aborted', 'err')
console.error(error)
alert(error)
badgeMinderClose()
}
}
alert('Gnome Screensaver successfully installed')
ipcRenderer.send('log', 'ORNL Toolbox: Completed install request for gnome-screensaver', 'info')
//Open Badge Minder window
addWinMain('./badgeManagement/badgeMinder/badgeMinder.html', 'Badge Minder', 450, 360)
}
......@@ -61,22 +61,6 @@
</div>
<select id="badgeMinderCarrier">
<option value="0" disabled selected>Carrier:</option>
<option value="1">AT&T</option>
<option value="2">Verizon</option>
<option value="3">U.S. Cellular</option>
<option value="4">Sprint</option>
<option value="5">Virgin Mobile</option>
<option value="6">T-Mobile</option>
<option value="7">Tracfone</option>
<option value="8">Metro PCS</option>
<option value="9">Boost Mobile</option>
<option value="10">Cricket</option>
<option value="11">Nextel</option>
<option value="12">Alltel</option>
<option value="13">Ptel</option>
<option value="14">Suncom</option>
<option value="15">Qwest</option>
<option value="16">Ting</option>
</select>
</div>
</div>
......
......@@ -8,6 +8,8 @@ const ipcRenderer = require('electron').ipcRenderer
const fs = require('fs')
function badgeConfig() {
ipcRenderer.send('log', `ORNL Toolbox: Submitted Badge Minder apply settings request`, 'info')
//For checking if the user chose beep, phone, both, or neither reminders
var enableBeeps = document.getElementById('badgeMinderBeepCheckBox').checked
var enableTxtmsg = document.getElementById('badgeMinderTextCheckBox').checked
......@@ -24,6 +26,7 @@ function badgeConfig() {
var regex = /^\d*(?:\.\d+)?$/ //Checks for 0 or more nums, a decimal, then 1 or more nums
if(! regex.test(beepTime)) {
alert('Invalid beepTime duration')
ipcRenderer.send('log', `ORNL Toolbox: Invalid Beep Reminder duration - request aborted`, 'err')
return
} else if(beepTime == "") {
/* Since there are 2.5 seconds between each beep, time is measured
......@@ -33,7 +36,17 @@ function badgeConfig() {
beepTime = beepTime * 24.0
}
beepTime = beepTime.toPrecision(7)
var logBeepTime = beepTime / 24.0
logBeepTime = logBeepTime.toPrecision(7)
ipcRenderer.send('log', `ORNL Toolbox: Beep Reminder is enabled`, 'info')
if(logBeepTime == 1.0) {
ipcRenderer.send('log', `ORNL Toolbox: Duration of Beeps is set to 1 minute`, 'info')
} else {
ipcRenderer.send('log', `ORNL Toolbox: Duration of Beeps is set to ${logBeepTime} minutes`, 'info')
}
} else {
ipcRenderer.send('log', `ORNL Toolbox: Beep Reminder is disabled`, 'info')
beepTime = 0
}
var beepTimeRounded = Math.round(beepTime)
......@@ -50,75 +63,48 @@ function badgeConfig() {
//Check if any of the phone number fields are invalid
if(parseInt(phoneNum1) == NaN || parseInt(phoneNum1) < 0 || /^[0-9]+$/.test(phoneNum1) == false || phoneNum1.length < 3) {
alert('Invalid 1st phone number field')
ipcRenderer.send('log', `ORNL Toolbox: Invalid 1st phone number field - request aborted`, 'err')
return
}
if(parseInt(phoneNum2) == NaN || parseInt(phoneNum2) < 0 || /^[0-9]+$/.test(phoneNum2) == false || phoneNum2.length < 3) {
alert('Invalid 2nd phone number field')
ipcRenderer.send('log', `ORNL Toolbox: Invalid 2nd phone number field - request aborted`, 'err')
return
}
if(parseInt(phoneNum3) == NaN || parseInt(phoneNum3) < 0 || /^[0-9]+$/.test(phoneNum3) == false || phoneNum3.length < 4) {
alert('Invalid 3rd phone number field')
ipcRenderer.send('log', `ORNL Toolbox: Invalid 3rd phone number field - request aborted`, 'err')
return
}
//Assigning a domain string to the carrier
switch(parseInt(carrier)) {
case 0:
alert('Invalid carrier') //No carrier is selected
return
break
case 1:
carrier = "@txt.att.net" //AT&T
break
case 2:
carrier = "@vtext.com" //Verizon
break
case 3:
carrier = "@email.uscc.net" //U.S. Cellular
break
case 4:
carrier = "@messaging.sprintpcs.com" //Sprint
break
case 5:
carrier = "@vmobl.com" //Virgin Mobile
break
case 6:
carrier = "@tmomail.net" //T-Mobile
break
case 7:
carrier = "@mmst5.tracfone.co" //Tracfone
break
case 8:
carrier = "@mymetropcs.com" //Metro PCS
break
case 9:
carrier = "@myboostmobile.com" //Boost Mobile
break
case 10:
carrier = "@sms.mycricket.com" //Cricket
break
case 11:
carrier = "@messaging.nextel.com" //Nextel
break
case 12:
carrier = "@message.alltel.com" //Alltel
break
case 13:
carrier = "@ptel.com" //Ptel
break
case 14:
carrier = "@tms.suncom.com" //Suncom
break
case 15:
carrier = "@qwestmp.com" //Qwest
carrier = parseInt(carrier)
//Grabs carriers.csv for list of carriers
var carriersPath = remote.app.getPath('exe') //Grabs the path to the executable
carriersPath = carriersPath.substring(0, carriersPath.length - 11) + 'resources/app/badgeManagement/badgeMinder/carriers.csv'
var carriers = fs.readFileSync(carriersPath, 'utf-8', () => {})
carriers = carriers.split(/,|\n/)
if(carrier == 0) { //No carrier is selected
alert('Invalid carrier')
ipcRenderer.send('log', `ORNL Toolbox: Invalid carrier - request aborted`, 'err')
return
}
for(i = 1; i < carriers.length; i+=2) {
if(i == carrier) {
carrier = carriers[parseInt(i / 2) + 1]
break
case 16:
carrier = "@mailmymobile.net" //Ting
}
}
//Combining the three phone number entries into one string
phone = `${phoneNum1}${phoneNum2}${phoneNum3}`
ipcRenderer.send('log', `ORNL Toolbox: Text Message Reminder is enabled`, 'info')
ipcRenderer.send('log', `ORNL Toolbox: Phone number is set to ${phone}`, 'info')
ipcRenderer.send('log', `ORNL Toolbox: Carrier is set to ${carrier}`, 'info')
} else {
ipcRenderer.send('log', `ORNL Toolbox: Text Message Reminder is disabled`, 'info')
//Text reminder is not enabled
phone = "none"
carrier = "none"
......@@ -140,6 +126,9 @@ function badgeConfig() {
fs.writeFile(path, `beepTime=${beepTime}\nbeepTimeRounded=${beepTimeRounded}\nphone=\"${phone}\"\ncarrier=\"${carrier}\"\n`, (error) => {
if(error) {
console.log(error)
ipcRenderer.send('log', `ORNL Toolbox: Error saving Badge Minder config file`, 'err')
} else {
ipcRenderer.send('log', `ORNL Toolbox: Badge Minder config file saved`, 'info')
}
//Block for killing old script and starting new one
......@@ -147,6 +136,7 @@ function badgeConfig() {
scriptStart = 'bash ' + scriptStart.substring(0, scriptStart.length - 11) + 'resources/app/badgeManagement/badgeMinder/badgeMinder.bash &'
try { //Kill the old reminder script if it exists
execSync('pkill -f badgeMinder.bash', () => {})
ipcRenderer.send('log', `ORNL Toolbox: Previous Badge Minder script killed`, 'info')
} catch(err) {
//Ignore that a process that doesn't exist can't be killed
}
......@@ -161,7 +151,9 @@ function badgeConfig() {
} catch(err) {
console.log(err)
console.log("Cannot start badgeMinder.bash")
ipcRenderer.send('log', `ORNL Toolbox: Failed to start Badge Minder script`, 'err')
}
ipcRenderer.send('log', `ORNL Toolbox: Badge Minder script started`, 'info')
//Block for writing in .xprofile startup script
try {
......
function badgeMinderClose() {
console.log('close')
if(!ipcRenderer) var ipcRenderer = require('electron').ipcRenderer
ipcRenderer.send('close minor window')
ipcRenderer.send('log', `ORNL Toolbox: Badge Minder closed`, 'info')
}
......@@ -22,6 +22,7 @@ function configLoad() {
var phone3
var carrier
//Grabs saved settings for Badge Minder
var contents = fs.readFileSync(remote.app.getPath('home') + '/.config/ornltoolbox/badgeMinder.config', 'utf-8', () => {})
contents = contents.split('\n')
......@@ -54,56 +55,26 @@ function configLoad() {
document.getElementById('badgeMinderPhoneTextBox2').value = phone2
document.getElementById('badgeMinderPhoneTextBox3').value = phone3
//Assigning a carrier number to the domain string
switch(carrier) {
case "@txt.att.net":
carrier = 1 //AT&T
break
case "@vtext.com":
carrier = 2 //Verizon
break
case "@email.uscc.net":
carrier = 3 //U.S. Cellular
break
case "@messaging.sprintpcs.com":
carrier = 4 //Sprint
break
case "@vmobl.com":
carrier = 5 //Virgin Mobile
break
case "@tmomail.net":
carrier = 6 //T-Mobile
break
case "@mmst5.tracfone.co":
carrier = 7 //Tracfone
break
case "@mymetropcs.com":
carrier = 8 //Metro PCS
break
case "@myboostmobile.com":
carrier = 9 //Boost Mobile
break
case "@sms.mycricket.com":
carrier = 10 //Cricket
break
case "@messaging.nextel.com":
carrier = 11 //Nextel
break
case "@message.alltel.com":
carrier = 12 //Alltel
break
case "@ptel.com":
carrier = 13 //Ptel
break
case "@tms.suncom.com":
carrier = 14 //Suncom
break
case "@qwestmp.com":
carrier = 15 //Qwest
break
case "@mailmymobile.net":
carrier = 16 //Ting
//Grabs carriers.csv for list of carriers
var carriersPath = remote.app.getPath('exe') //Grabs the path to the executable
carriersPath = carriersPath.substring(0, carriersPath.length - 11) + 'resources/app/badgeManagement/badgeMinder/carriers.csv'
var carriers = fs.readFileSync(carriersPath, 'utf-8', () => {})
carriers = carriers.split(/,|\n/)