From 70d1d9a96498a6c37cfcc3b9ae106edc81b2e9c4 Mon Sep 17 00:00:00 2001
From: maryamsaleem <maryamsaleem874@gmail.com>
Date: Thu, 6 Feb 2025 14:57:09 +0500
Subject: [PATCH] lint issues resolved

---
 server/model/monitor.js                      |  25 ++-
 server/notification-providers/sip.js         |  53 ++++--
 server/util-server.js                        |  84 +++++----
 src/modules/dayjs/plugin/timezone/index.d.ts |  10 +-
 src/pages/EditMonitor.vue                    | 176 ++++++++++---------
 5 files changed, 202 insertions(+), 146 deletions(-)

diff --git a/server/model/monitor.js b/server/model/monitor.js
index fed3278de..67d711e7e 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -5,7 +5,7 @@ const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MI
     SQL_DATETIME_FORMAT, evaluateJsonQuery
 } = require("../../src/util");
 const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, setSetting, httpNtlm, radius, grpcQuery,
-    redisPingAsync, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal, sipRegisterRequest,sipOptionRequest
+    redisPingAsync, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal, sipRegisterRequest, sipOptionRequest
 } = require("../util-server");
 const { R } = require("redbean-node");
 const { BeanModel } = require("redbean-node/dist/bean-model");
@@ -315,9 +315,9 @@ class Monitor extends BeanModel {
             sipUrl: this.sipUrl,
             sipPort: this.sipPort,
             sipProtocol: this.sipProtocol,
-			sipMethod: this.sipMethod,
-			sipMaintainence: this.isSipMaintainence(),
-			sipAuthMethod: this.sipAuthMethod,
+            sipMethod: this.sipMethod,
+            sipMaintainence: this.isSipMaintainence(),
+            sipAuthMethod: this.sipAuthMethod,
         };
 
         if (includeSensitiveData) {
@@ -483,6 +483,7 @@ class Monitor extends BeanModel {
     getKafkaProducerAllowAutoTopicCreation() {
         return Boolean(this.kafkaProducerAllowAutoTopicCreation);
     }
+
     /**
      * Parse to boolean
      * @returns {boolean} Sip Allow Maintainenece Option
@@ -490,6 +491,7 @@ class Monitor extends BeanModel {
     isSipMaintainence() {
         return Boolean(this.sipMaintainence);
     }
+
     /**
      * Start monitor
      * @param {Server} io Socket server instance
@@ -1052,12 +1054,11 @@ class Monitor extends BeanModel {
                         let sipMessage;
                         let startTime = dayjs().valueOf();
                         let totalResponseTime;
-                        let requestCount;
                         if (this.sipMethod !== "OPTIONS") {
                             sipResponse = await sipRegisterRequest(this.sipUrl, this.sipPort, this.sipProtocol, this.sip_basic_auth_user, this.sip_basic_auth_pass, version);
                             let sipResponseTime = dayjs().valueOf() - startTime;
                             totalResponseTime += sipResponseTime;
-                            console.log("sipResponse", sipResponse);
+                            console.log("sipResponse", totalResponseTime);
                             console.log("this.sipMaintainence", this.sipMaintainence);
                             const matchingStatus = sipStatusCodes.find(code => code.status === sipResponse?.status);
                             if (matchingStatus) {
@@ -1066,7 +1067,7 @@ class Monitor extends BeanModel {
                                 bean.status = sipResponse?.status === 200 ? UP : DOWN;
                                 console.log("sipResponse?.status", sipResponse?.status);
                                 // Additional check for 503 status within matchingStatus
-                                if (sipResponse?.status === 503 && this.sipMaintainence == 1) {
+                                if (sipResponse?.status === 503 && this.sipMaintainence === 1) {
                                     sipMessage = "Monitor under maintenance";
                                     bean.status = MAINTENANCE;
                                 }
@@ -1074,12 +1075,9 @@ class Monitor extends BeanModel {
                                 sipMessage = ` ${sipResponse?.status}-Not Ok`;
                                 bean.status = DOWN;
                             }
-                   
+
                         } else if (this.sipMethod === "OPTIONS") {
                             sipResponse = await sipOptionRequest(this.sipUrl, this.sipPort, this.sipProtocol, this.sip_basic_auth_user, this.sip_basic_auth_pass, version);
-                            let sipOptionsResponseTime = dayjs().valueOf() - startTime;
-                            totalResponseTime = sipOptionsResponseTime;
-                            requestCount++;
                             console.log("=====resposne status", sipResponse?.status);
                             console.log("this.sipMaintainence", this.sipMaintainence);
                             const matchingStatus = sipStatusCodes.find(code => code.status === sipResponse?.status);
@@ -1089,7 +1087,7 @@ class Monitor extends BeanModel {
                                 bean.status = sipResponse?.status === 200 ? UP : DOWN;
 
                                 // Additional check for 503 status within matchingStatus
-                                if (sipResponse?.status === 503 && this.sipMaintainence == 1) {
+                                if (sipResponse?.status === 503 && this.sipMaintainence === 1) {
                                     sipMessage = "Monitor under maintenance";
                                     bean.status = MAINTENANCE;
                                 }
@@ -1105,8 +1103,7 @@ class Monitor extends BeanModel {
                         bean.msg = `Error: ${error.message}`;
                         bean.status = DOWN;
                     }
-                }
-                else {
+                } else {
                     throw new Error("Unknown Monitor Type");
                 }
 
diff --git a/server/notification-providers/sip.js b/server/notification-providers/sip.js
index 19c8959ce..86c1e2687 100644
--- a/server/notification-providers/sip.js
+++ b/server/notification-providers/sip.js
@@ -2,14 +2,29 @@ const NotificationProvider = require("./notification-provider");
 
 class SIP extends NotificationProvider {
     name = "sip";
+
+    /**
+     * Sends a SIP notification message.
+     * @param {object} notification - SIP notification configuration.
+     * @param {string} msg - The message content.
+     * @param {object | null} monitorJSON - The monitor data (if available).
+     * @param {object | null} heartbeatJSON - The heartbeat data (if available).
+     * @returns {Promise<string>} - Confirmation message if successful.
+     * @throws {Error} - If sending the SIP message fails.
+     */
     async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
         let monitorName = monitorJSON ? monitorJSON["name"] : "Unknown Monitor";
-        let subject = this.updateSubject(msg, monitorName);
-        let body;
+        let body = "";
+
         if (heartbeatJSON) {
             body += `\nTime (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
         }
+
         try {
+            console.log("Sending SIP message:", { notification,
+                msg,
+                monitorName,
+                body });
             return "SIP Message Sent Successfully.";
         } catch (error) {
             console.error("Error sending SIP message:", error);
@@ -17,44 +32,58 @@ class SIP extends NotificationProvider {
         }
     }
 
+    /**
+     * Generates a subject line based on the message content.
+     * @param {string} message - The incoming status message.
+     * @param {string} monitorName - The name of the monitored service.
+     * @returns {string} - The formatted subject line.
+     */
     updateSubject(message, monitorName) {
-        if (!message) return "Default Subject"; // Handle null/undefined message
+        if (!message) {
+            return "Default Subject";
+        }
 
         message = message.toLowerCase(); // Normalize input
 
         if (/\bdown\b/i.test(message) || message.includes("offline")) {
-            return `🚨 ❌ Service Impacted...`;
+            return "🚨 ❌ Service Impacted...";
         }
         if (/\bup\b/i.test(message) || message.includes("online")) {
-            return `🚨 ✅ Service Restored...`;
+            return "🚨 ✅ Service Restored...";
         }
         if (message.includes("maintenance")) {
             if (message.includes("begin")) {
-                return `🚧 🔧 ❌  Maintenance Start...`;
+                return "🚧 🔧 ❌ Maintenance Start...";
             }
             if (/\bend\b/i.test(message)) {
-                return `🚧 🔧 ✅ Maintenance Complete...`;
+                return "🚧 🔧 ✅ Maintenance Complete...";
             }
             if (message.includes("scheduled")) {
-                return `🚧 🪟 📆  Maintenance Window Scheduled...`;
+                return "🚧 🪟 📆 Maintenance Window Scheduled...";
             }
             if (message.includes("window begin")) {
-                return `🚧 🪟 🛑  Maintenance Window Start...`;
+                return "🚧 🪟 🛑 Maintenance Window Start...";
             }
             if (message.includes("window end")) {
-                return `🚧 🪟 ✅  Maintenance Window Complete...`;
+                return "🚧 🪟 ✅ Maintenance Window Complete...";
             }
         }
         if (message.includes("started on node")) {
-            return `📈 🔬 ✅  Monitoring Start...`;
+            return "📈 🔬 ✅ Monitoring Start...";
         }
         if (message.includes("started")) {
-            return `📈 🔬 ✅  ${monitorName}`;
+            return `📈 🔬 ✅ ${monitorName}`;
         }
 
         return "Default Subject";
     }
 
+    /**
+     * Sends a SIP message using the provided notification configuration.
+     * @param {object} notification - SIP notification settings.
+     * @param {string} sipMessage - The message content to send.
+     * @returns {void}
+     */
     async sendSIPMessage(notification, sipMessage) {
         console.log("Sending SIP message with config:", notification);
         console.log("Message:", sipMessage);
diff --git a/server/util-server.js b/server/util-server.js
index 9101d3e30..4534b9198 100644
--- a/server/util-server.js
+++ b/server/util-server.js
@@ -33,8 +33,6 @@ const { Kafka, SASLOptions } = require("kafkajs");
 const crypto = require("crypto");
 let sip = require("sip");
 const uuid = require("uuid");
-let sharedSipServer;
-const SERVER_PORT = 25060;
 
 const isWindows = process.platform === /^win/.test(process.platform);
 /**
@@ -266,23 +264,28 @@ exports.kafkaProducerAsync = function (brokers, topic, message, options = {}, sa
 /**
  * Sends a SIP REGISTER request
  * @param {string} sipServer The SIP server to register with
+ * @param {number} sipPort The port of the SIP server
  * @param {string} transport The transport protocol to use (e.g., 'udp' or 'tcp')
- * @returns {Promise<void>}
+ * @param {string} username The username for registration
+ * @param {string} password The password for registration
+ * @param {string} version The version of the SIP health monitor
+ * @returns {Promise<object>} The response from the SIP REGISTER request
  */
 exports.sipRegisterRequest = function (sipServer, sipPort, transport, username, password, version) {
-  
+
     // eslint-disable-next-line no-async-promise-executor
     return new Promise(async (resolve, reject) => {
         try {
             const registerRequest = {
-                method: 'REGISTER',
+                method: "REGISTER",
                 uri: `sip:${sipServer}:${sipPort}`,
                 headers: {
                     to: { uri: `sip:${sipServer}:${sipPort}` },
                     from: { uri: `sip:${username}` },
-                    'call-id': uuid.v4(),
-                    cseq: { method: 'REGISTER', seq: 1 },
-                    'content-length': 0,
+                    "call-id": uuid.v4(),
+                    cseq: { method: "REGISTER",
+                        seq: 1 },
+                    "content-length": 0,
                     contact: { uri: `sip:${username}` },
                     "User-Agent": "SIP Health Monitor " + version,
                     "Expires": 60,
@@ -321,9 +324,16 @@ exports.sipRegister = function (registerRequest) {
     return new Promise((resolve, reject) => {
         const timeout = 5000; // Timeout duration in milliseconds
         let timeoutID;
-        // Cleanup function to clear the timeout and destroy the server
+        // Cleanup function to ensure proper resource management
+        /**
+         * Clears the timeout and destroys the SIP server instance.
+         * This function is called to prevent memory leaks and ensure that no lingering processes are left running.
+         * @returns {void} This function does not return any value.
+         */
         function cleanup() {
-            if (timeoutID) clearTimeout(timeoutID);
+            if (timeoutID) {
+                clearTimeout(timeoutID);
+            }
             if (server && server.destroy) {
                 server.destroy();
                 console.log("SIP server destroyed.");
@@ -378,8 +388,12 @@ exports.constructAuthorizedRequest = function (request, username, password, prox
 /**
  * Sends a SIP OPTIONS request
  * @param {string} sipServer The SIP server to send OPTIONS to
+ * @param {number} sipPort The port of the SIP server
  * @param {string} transport The transport protocol to use (e.g., 'udp' or 'tcp')
- * @returns {Promise<void>}
+ * @param {string} username The username for authentication (optional)
+ * @param {string} password The password for authentication (optional)
+ * @param {string} version The version of the SIP Health Monitor
+ * @returns {Promise<object>} The response from the SIP OPTIONS request
  */
 exports.sipOptionRequest = function (sipServer, sipPort, transport, username, password, version) {
     const publicIP = process.env.PUBLIC_IP;
@@ -387,28 +401,28 @@ exports.sipOptionRequest = function (sipServer, sipPort, transport, username, pa
     return new Promise(async (resolve, reject) => {
         try {
             const optionsRequest = {
-                method: 'OPTIONS',
-                uri: `sip:${sipServer}:${sipPort}`,//hostname
+                method: "OPTIONS",
+                uri: `sip:${sipServer}:${sipPort}`, //hostname
                 headers: {
-                    to: { uri: `sip:${sipServer}:${sipPort}` },//hostname
-                    from: { uri:    `sip:${publicIP}` },//live ip || primary url
-                    'call-id': 1234,
-                    cseq: { method: 'OPTIONS', seq: 1 },
-                    'content-length': 0,
-                    contact: [ { uri:    `sip:${publicIP}` }],
+                    to: { uri: `sip:${sipServer}:${sipPort}` }, //hostname
+                    from: { uri: `sip:${publicIP}` }, //live ip || primary url
+                    "call-id": 1234,
+                    cseq: { method: "OPTIONS",
+                        seq: 1 },
+                    "content-length": 0,
+                    contact: [{ uri: `sip:${publicIP}` }],
                     "User-Agent": "SIP Health Monitor" + version,
 
                 },
                 transport: transport,
             };
-            let optionResponse
-            if(!username) {
-                console.log("will only send ok")
+            let optionResponse;
+            if (!username) {
+                console.log("will only send ok");
                 const optionResponse = await exports.sipOption(optionsRequest);
                 console.log("optionResponse", optionResponse);
-                resolve(optionResponse)
-            }
-            else {
+                resolve(optionResponse);
+            } else {
                 optionResponse = await exports.sipRegister(optionsRequest);
                 console.log("optionResponse", optionResponse);
                 if (optionResponse.status === 407 && optionResponse.headers["proxy-authenticate"]) {
@@ -419,12 +433,12 @@ exports.sipOptionRequest = function (sipServer, sipPort, transport, username, pa
                         password,
                         proxyAuthenticateHeader
                     );
-    
+
                     const secondResponse = await exports.sipOption(authorizedOptionRequest);
                     resolve(secondResponse);
-                } 
+                }
             }
-       
+
         } catch (error) {
             console.error("Error:", error.message);
             reject(error);
@@ -439,18 +453,24 @@ exports.sipOption = function (optionsRequest) {
 
     console.log("SIP server created:", server);
     return new Promise((resolve, reject) => {
-        const timeout = 5000; // Timeout duration in milliseconds
+
         let timeoutID;
-        // Cleanup function to clear the timeout and destroy the server
+        // Cleanup function to ensure proper resource management
+        /**
+         * Clears the timeout and destroys the SIP server instance.
+         * This function is called to prevent memory leaks and ensure that no lingering processes are left running.
+         * @returns {void} This function does not return any value.
+         */
         function cleanup() {
-            if (timeoutID) clearTimeout(timeoutID);
+            if (timeoutID) {
+                clearTimeout(timeoutID);
+            }
             if (server) {
                 server.destroy();
                 console.log("SIP server destroyed.");
             }
         }
 
-
         try {
             // Send the SIP options request
             server.send(optionsRequest, (response) => {
diff --git a/src/modules/dayjs/plugin/timezone/index.d.ts b/src/modules/dayjs/plugin/timezone/index.d.ts
index 8d9035905..e9e5a48f8 100644
--- a/src/modules/dayjs/plugin/timezone/index.d.ts
+++ b/src/modules/dayjs/plugin/timezone/index.d.ts
@@ -1,12 +1,12 @@
-import { PluginFunc, ConfigType } from 'dayjs/esm'
+import { PluginFunc, ConfigType } from "dayjs/esm";
 
-declare const plugin: PluginFunc
+declare const plugin: PluginFunc;
 export = plugin
 
-declare module 'dayjs/esm' {
+declare module "dayjs/esm" {
   interface Dayjs {
     tz(timezone?: string, keepLocalTime?: boolean): Dayjs
-    offsetName(type?: 'short' | 'long'): string | undefined
+    offsetName(type?: "short" | "long"): string | undefined
   }
 
   interface DayjsTimezone {
@@ -16,5 +16,5 @@ declare module 'dayjs/esm' {
     setDefault(timezone?: string): void
   }
 
-  const tz: DayjsTimezone
+  const tz: DayjsTimezone;
 }
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index 745969a56..c83887d1a 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -91,7 +91,7 @@
                                         <option v-if="!$root.info.isContainer" value="tailscale-ping">
                                             Tailscale Ping
                                         </option>
-                                          <option value="sip">SIP</option>
+                                        <option value="sip">SIP</option>
                                     </optgroup>
                                 </select>
                                 <i18n-t v-if="monitor.type === 'rabbitmq'" keypath="rabbitmqHelpText" tag="div" class="form-text">
@@ -121,10 +121,10 @@
                             <!--SIP-->
                             <div v-if="monitor.type === 'sip'" class="my-3">
                                 <label for="sipprotocol" class="form-label">{{ $t("SipProtocol") }}</label>
-                                <select id="sipprotocol" class="form-select" required v-model="monitor.sipProtocol">
-                                <option value="UDP">UDP</option>
-                                <option value="TCP">TCP</option>
-                                <option value="TLS">TLS</option>
+                                <select id="sipprotocol" v-model="monitor.sipProtocol" class="form-select" required>
+                                    <option value="UDP">UDP</option>
+                                    <option value="TCP">TCP</option>
+                                    <option value="TLS">TLS</option>
                                 </select>
                             </div>
                             <!-- gRPC URL -->
@@ -175,8 +175,10 @@
                             </div>
                             <div v-if="monitor.type === 'sip'" class="my-3">
                                 <label for="sipport" class="form-label mt-3">{{ $t("SipPort") }}</label>
-                                <input v-if="monitor.sipProtocol !== 'SRV'" id="sipport" type="number" class="form-control"
-                                v-model="monitor.sipPort" placeholder="Enter SIP Port">
+                                <input
+                                    v-if="monitor.sipProtocol !== 'SRV'" id="sipport" v-model="monitor.sipPort" type="number"
+                                    class="form-control" placeholder="Enter SIP Port"
+                                >
                             </div>
                             <!-- Remote Browser -->
                             <div v-if="monitor.type === 'real-browser'" class="my-3">
@@ -637,7 +639,7 @@
                                 <input id="expiry-notification" v-model="monitor.expiryNotification" class="form-check-input" type="checkbox" :disabled="monitor.ignoreTls">
                                 <label class="form-check-label" for="expiry-notification">
                                     {{ $t("Certificate Expiry Notification") }}
-                                </label> 
+                                </label>
                                 <div class="form-text">
                                 </div>
                             </div>
@@ -681,8 +683,8 @@
                                 <label class="form-check-label" for="process-503-as-maintenance">
                                     {{ $t("process503AsMaintenanceLabel") }}
                                 </label>
-                                </div>
-  
+                            </div>
+
                             <div v-if="monitor.type === 'gamedig'" class="my-3 form-check">
                                 <input id="gamedig-guess-port" v-model="monitor.gamedigGivenPortOnly" :true-value="false" :false-value="true" class="form-check-input" type="checkbox">
                                 <label class="form-check-label" for="gamedig-guess-port">
@@ -858,83 +860,91 @@
                                     </div>
                                 </div>
                             </template>
-     <!-- SIP Options -->
-             
-  <template v-if="monitor.type === 'sip'
-                ">
-                <h2 class="mt-5 mb-2">{{ $t("SIP Options") }}</h2>
+                            <!-- SIP Options -->
 
-                <!-- Method -->
-                <div class="my-3">
-                  <label for="method" class="form-label">{{
-                    $t("Method")
-                  }}</label>
-                  <select id="method" v-model="monitor.sipMethod" class="form-select">
-                 
-                    <option value="REGISTER">REGISTER</option>
-                    <option value="OPTIONS">OPTIONS</option>
-                  </select>
-                </div>
+                            <template
+                                v-if="monitor.type === 'sip'
+                                "
+                            >
+                                <h2 class="mt-5 mb-2">{{ $t("SIP Options") }}</h2>
 
-                <!-- Encoding -->
-                <div class="my-3">
-                  <label for="httpBodyEncoding" class="form-label">{{
-                    $t("Body Encoding")
-                  }}</label>
-                  <select id="httpBodyEncoding" v-model="monitor.httpBodyEncoding" class="form-select">
-                    <option value="json">JSON</option>
-                    <option value="xml">XML</option>
-                  </select>
-                </div>
+                                <!-- Method -->
+                                <div class="my-3">
+                                    <label for="method" class="form-label">{{
+                                        $t("Method")
+                                    }}</label>
+                                    <select id="method" v-model="monitor.sipMethod" class="form-select">
+                                        <option value="REGISTER">REGISTER</option>
+                                        <option value="OPTIONS">OPTIONS</option>
+                                    </select>
+                                </div>
 
-                <!-- Body -->
-                <div class="my-3">
-                  <label for="body" class="form-label">{{ $t("Body") }}</label>
-                  <textarea id="body" v-model="monitor.body" class="form-control"
-                    :placeholder="bodyPlaceholder"></textarea>
-                </div>
+                                <!-- Encoding -->
+                                <div class="my-3">
+                                    <label for="httpBodyEncoding" class="form-label">{{
+                                        $t("Body Encoding")
+                                    }}</label>
+                                    <select id="httpBodyEncoding" v-model="monitor.httpBodyEncoding" class="form-select">
+                                        <option value="json">JSON</option>
+                                        <option value="xml">XML</option>
+                                    </select>
+                                </div>
 
-                <!-- Headers -->
-                <div class="my-3">
-                  <label for="headers" class="form-label">{{
-                    $t("Headers")
-                  }}</label>
-                  <textarea id="headers" v-model="monitor.headers" class="form-control"
-                    :placeholder="headersPlaceholder"></textarea>
-                </div>
+                                <!-- Body -->
+                                <div class="my-3">
+                                    <label for="body" class="form-label">{{ $t("Body") }}</label>
+                                    <textarea
+                                        id="body" v-model="monitor.body" class="form-control"
+                                        :placeholder="bodyPlaceholder"
+                                    ></textarea>
+                                </div>
 
-                <!-- HTTP Auth -->
-                <h4 class="mt-5 mb-2">{{ $t("Authentication") }}</h4>
+                                <!-- Headers -->
+                                <div class="my-3">
+                                    <label for="headers" class="form-label">{{
+                                        $t("Headers")
+                                    }}</label>
+                                    <textarea
+                                        id="headers" v-model="monitor.headers" class="form-control"
+                                        :placeholder="headersPlaceholder"
+                                    ></textarea>
+                                </div>
 
-                <!-- Method -->
-                <div class="my-3">
-                  <label for="authmethod" class="form-label">{{
-                    $t("Method")
-                  }}</label>
-                  <select id="authsipmethod" v-model="monitor.sipAuthMethod" class="form-select">
-                    <option :value="null">
-                      {{ $t("None") }}
-                    </option>
-                    <option value="basic">
-                      {{ $t("SIP Basic Auth") }}
-                    </option>
-                   
-                  </select>
-                </div>
-                <template v-if="monitor.sipAuthMethod === 'basic'">
-  <div class="my-3">
-    <label for="basicauth-user" class="form-label">{{ $t("Username") }}</label>
-    <input id="basicauth-user" v-model="monitor.sip_basic_auth_user" type="text" class="form-control"
-      :placeholder="$t('Username')" />
-  </div>
+                                <!-- HTTP Auth -->
+                                <h4 class="mt-5 mb-2">{{ $t("Authentication") }}</h4>
 
-  <div class="my-3">
-    <label for="basicauth-pass" class="form-label">{{ $t("Password") }}</label>
-    <input id="basicauth-pass" v-model="monitor.sip_basic_auth_pass" type="password" autocomplete="new-password"
-      class="form-control" :placeholder="$t('Password')" />
-  </div>
-</template>
-              </template>
+                                <!-- Method -->
+                                <div class="my-3">
+                                    <label for="authmethod" class="form-label">{{
+                                        $t("Method")
+                                    }}</label>
+                                    <select id="authsipmethod" v-model="monitor.sipAuthMethod" class="form-select">
+                                        <option :value="null">
+                                            {{ $t("None") }}
+                                        </option>
+                                        <option value="basic">
+                                            {{ $t("SIP Basic Auth") }}
+                                        </option>
+                                    </select>
+                                </div>
+                                <template v-if="monitor.sipAuthMethod === 'basic'">
+                                    <div class="my-3">
+                                        <label for="basicauth-user" class="form-label">{{ $t("Username") }}</label>
+                                        <input
+                                            id="basicauth-user" v-model="monitor.sip_basic_auth_user" type="text" class="form-control"
+                                            :placeholder="$t('Username')"
+                                        />
+                                    </div>
+
+                                    <div class="my-3">
+                                        <label for="basicauth-pass" class="form-label">{{ $t("Password") }}</label>
+                                        <input
+                                            id="basicauth-pass" v-model="monitor.sip_basic_auth_pass" type="password" autocomplete="new-password"
+                                            class="form-control" :placeholder="$t('Password')"
+                                        />
+                                    </div>
+                                </template>
+                            </template>
                             <!-- HTTP Options -->
                             <template v-if="monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'json-query' ">
                                 <h2 class="mt-5 mb-2">{{ $t("HTTP Options") }}</h2>
@@ -1223,10 +1233,10 @@ const monitorDefaults = {
     conditions: [],
     sipProtocol: "UDP",
     sipPort: 5060,
-    sipUrl:null,
+    sipUrl: null,
     sipMethod: "OPTIONS",
-	sipMaintainence:false,
-	sipAuthMethod: null,
+    sipMaintainence: false,
+    sipAuthMethod: null,
 };
 
 export default {