mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2026-02-09 02:29:45 +00:00
Compare commits
7 Commits
v0.8.2-rc7
...
snyk-fix-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27cb05e22a | ||
|
|
aba8b2be3a | ||
|
|
f4d7880ab7 | ||
|
|
7f93489580 | ||
|
|
19fafdc908 | ||
|
|
a165bfc4d6 | ||
|
|
e26d9b95cb |
@@ -6,7 +6,7 @@ RUN npm install
|
||||
RUN npm run build
|
||||
RUN npm prune
|
||||
|
||||
FROM node:18.14.1-alpine as webapp
|
||||
FROM node:18.15-alpine as webapp
|
||||
RUN apk add curl
|
||||
WORKDIR /opt/app
|
||||
COPY . /opt/app
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "jambonz-webapp",
|
||||
"version": "v1.0.0",
|
||||
"version": "v0.8.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "jambonz-webapp",
|
||||
"version": "v1.0.0",
|
||||
"version": "v0.8.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jambonz-webapp",
|
||||
"description": "A simple provisioning web app for jambonz",
|
||||
"version": "v1.0.0",
|
||||
"version": "v0.8.2",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
|
||||
@@ -189,6 +189,7 @@ export const CRED_NOT_TESTED = "not tested";
|
||||
|
||||
/** API base paths */
|
||||
export const API_LOGIN = `${API_BASE_URL}/login`;
|
||||
export const API_LOGOUT = `${API_BASE_URL}/logout`;
|
||||
export const API_SBCS = `${API_BASE_URL}/Sbcs`;
|
||||
export const API_USERS = `${API_BASE_URL}/Users`;
|
||||
export const API_API_KEYS = `${API_BASE_URL}/ApiKeys`;
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
API_SIP_GATEWAY,
|
||||
API_PASSWORD_SETTINGS,
|
||||
USER_ACCOUNT,
|
||||
API_LOGOUT,
|
||||
} from "./constants";
|
||||
import { ROUTE_LOGIN } from "src/router/routes";
|
||||
import {
|
||||
@@ -233,6 +234,10 @@ export const postLogin = (payload: UserLoginPayload) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const postLogout = () => {
|
||||
return postFetch<undefined>(API_LOGOUT);
|
||||
};
|
||||
|
||||
/** Named wrappers for `postFetch` */
|
||||
|
||||
export const postServiceProviders = (payload: Partial<ServiceProvider>) => {
|
||||
|
||||
@@ -303,6 +303,8 @@ export interface SpeechCredential {
|
||||
custom_stt_endpoint: null | string;
|
||||
client_id: null | string;
|
||||
secret: null | string;
|
||||
nuance_tts_uri: null | string;
|
||||
nuance_stt_uri: null | string;
|
||||
tts_api_key: null | string;
|
||||
tts_region: null | string;
|
||||
stt_api_key: null | string;
|
||||
|
||||
@@ -72,11 +72,17 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
const [initialApplicationJson, setInitialApplicationJson] = useState(false);
|
||||
const [accountSid, setAccountSid] = useState("");
|
||||
const [callWebhook, setCallWebhook] = useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [tmpCallWebhook, setTmpCallWebhook] =
|
||||
useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [initialCallWebhook, setInitialCallWebhook] = useState(false);
|
||||
const [statusWebhook, setStatusWebhook] = useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [tmpStatusWebhook, setTmpStatusWebhook] =
|
||||
useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [initialStatusWebhook, setInitialStatusWebhook] = useState(false);
|
||||
const [messageWebhook, setMessageWebhook] =
|
||||
useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [tmpMessageWebhook, setTmpMessageWebhook] =
|
||||
useState<WebHook>(DEFAULT_WEBHOOK);
|
||||
const [initialMessageWebhook, setInitialMessageWebhook] = useState(false);
|
||||
const [synthVendor, setSynthVendor] =
|
||||
useState<keyof SynthesisVendors>(VENDOR_GOOGLE);
|
||||
@@ -97,7 +103,9 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
label: "Calling",
|
||||
prefix: "call_webhook",
|
||||
stateVal: callWebhook,
|
||||
tmpStateVal: tmpCallWebhook,
|
||||
stateSet: setCallWebhook,
|
||||
tmpStateSet: setTmpCallWebhook,
|
||||
initialCheck: initialCallWebhook,
|
||||
required: true,
|
||||
},
|
||||
@@ -105,7 +113,9 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
label: "Call status",
|
||||
prefix: "status_webhook",
|
||||
stateVal: statusWebhook,
|
||||
tmpStateVal: tmpStatusWebhook,
|
||||
stateSet: setStatusWebhook,
|
||||
tmpStateSet: setTmpStatusWebhook,
|
||||
initialCheck: initialStatusWebhook,
|
||||
required: true,
|
||||
},
|
||||
@@ -113,7 +123,9 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
label: "Messaging",
|
||||
prefix: "message_webhook",
|
||||
stateVal: messageWebhook,
|
||||
tmpStateVal: tmpMessageWebhook,
|
||||
stateSet: setMessageWebhook,
|
||||
tmpStateSet: setTmpMessageWebhook,
|
||||
initialCheck: initialMessageWebhook,
|
||||
required: false,
|
||||
},
|
||||
@@ -242,6 +254,7 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
|
||||
if (application.data.call_hook) {
|
||||
setCallWebhook(application.data.call_hook);
|
||||
setTmpCallWebhook(application.data.call_hook);
|
||||
|
||||
if (
|
||||
application.data.call_hook.username ||
|
||||
@@ -253,6 +266,7 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
|
||||
if (application.data.call_status_hook) {
|
||||
setStatusWebhook(application.data.call_status_hook);
|
||||
setTmpStatusWebhook(application.data.call_status_hook);
|
||||
|
||||
if (
|
||||
application.data.call_status_hook.username ||
|
||||
@@ -264,6 +278,7 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
|
||||
if (application.data.messaging_hook) {
|
||||
setMessageWebhook(application.data.messaging_hook);
|
||||
setTmpMessageWebhook(application.data.messaging_hook);
|
||||
|
||||
if (
|
||||
application.data.messaging_hook.username ||
|
||||
@@ -383,6 +398,18 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
name={webhook.prefix}
|
||||
label="Use HTTP basic authentication"
|
||||
initialCheck={webhook.initialCheck}
|
||||
handleChecked={(e) => {
|
||||
if (e.target.checked) {
|
||||
webhook.stateSet(webhook.tmpStateVal);
|
||||
} else {
|
||||
webhook.tmpStateSet(webhook.stateVal);
|
||||
webhook.stateSet({
|
||||
...webhook.stateVal,
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<MS>{MSG_WEBHOOK_FIELDS}</MS>
|
||||
<label htmlFor={`${webhook.prefix}_username`}>Username</label>
|
||||
|
||||
@@ -89,6 +89,16 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [customVendorTtsUrl, setCustomVendorTtsUrl] = useState("");
|
||||
const [tmpCustomVendorSttUrl, setTmpCustomVendorSttUrl] = useState("");
|
||||
const [customVendorSttUrl, setCustomVendorSttUrl] = useState("");
|
||||
const [initialOnPremNuanceTtsCheck, setInitialOnPremNuanceTtsCheck] =
|
||||
useState(false);
|
||||
const [onPremNuanceTtsCheck, setOnPremNuanceTtsCheck] = useState(false);
|
||||
const [onPremNuanceTtsUrl, setOnPremNuanceTtsUrl] = useState("");
|
||||
const [tmpOnPremNuanceTtsUrl, setTmpOnPremNuanceTtsUrl] = useState("");
|
||||
const [initialOnPremNuanceSttCheck, setInitialOnPremNuanceSttCheck] =
|
||||
useState(false);
|
||||
const [onPremNuanceSttCheck, setOnPremNuanceSttCheck] = useState(false);
|
||||
const [tmpOnPremNuanceSttUrl, setTmpOnPremNuanceSttUrl] = useState("");
|
||||
const [onPremNuanceSttUrl, setOnPremNuanceSttUrl] = useState("");
|
||||
|
||||
const handleFile = (file: File) => {
|
||||
const handleError = () => {
|
||||
@@ -161,6 +171,12 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
custom_stt_url: customVendorSttUrl || null,
|
||||
auth_token: customVendorAuthToken || null,
|
||||
}),
|
||||
...(vendor === VENDOR_NUANCE && {
|
||||
client_id: clientId || null,
|
||||
secret: secretKey || null,
|
||||
nuance_tts_uri: onPremNuanceTtsUrl || null,
|
||||
nuance_stt_uri: onPremNuanceSttUrl || null,
|
||||
}),
|
||||
};
|
||||
|
||||
if (credential && credential.data) {
|
||||
@@ -197,8 +213,6 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor === VENDOR_SONIOX
|
||||
? apiKey
|
||||
: null,
|
||||
client_id: vendor === VENDOR_NUANCE ? clientId : null,
|
||||
secret: vendor === VENDOR_NUANCE ? secretKey : null,
|
||||
riva_server_uri: vendor == VENDOR_NVIDIA ? rivaServerUri : null,
|
||||
})
|
||||
.then(() => {
|
||||
@@ -219,7 +233,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
if (credential.data.vendor) {
|
||||
const v = credential.data.vendor.startsWith(VENDOR_CUSTOM)
|
||||
? VENDOR_CUSTOM
|
||||
: vendor;
|
||||
: credential.data.vendor;
|
||||
setVendor(v);
|
||||
}
|
||||
|
||||
@@ -275,6 +289,24 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setSecretKey(credential.data.secret);
|
||||
}
|
||||
|
||||
if (credential.data.nuance_tts_uri) {
|
||||
setOnPremNuanceTtsUrl(credential.data.nuance_tts_uri);
|
||||
setInitialOnPremNuanceTtsCheck(true);
|
||||
setOnPremNuanceTtsCheck(true);
|
||||
} else {
|
||||
setInitialOnPremNuanceTtsCheck(false);
|
||||
setOnPremNuanceTtsCheck(false);
|
||||
}
|
||||
|
||||
if (credential.data.nuance_stt_uri) {
|
||||
setOnPremNuanceSttUrl(credential.data.nuance_stt_uri);
|
||||
setInitialOnPremNuanceSttCheck(true);
|
||||
setOnPremNuanceSttCheck(true);
|
||||
} else {
|
||||
setInitialOnPremNuanceSttCheck(false);
|
||||
setOnPremNuanceSttCheck(false);
|
||||
}
|
||||
|
||||
if (credential.data.tts_api_key) {
|
||||
setTtsApiKey(credential.data.tts_api_key);
|
||||
}
|
||||
@@ -527,33 +559,108 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
</>
|
||||
)}
|
||||
{vendor === VENDOR_NUANCE && (
|
||||
<fieldset>
|
||||
<label htmlFor="nuance_client_id">
|
||||
Client ID<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="nuance_client_id"
|
||||
required
|
||||
type="text"
|
||||
name="nuance_client_id"
|
||||
placeholder="Client ID"
|
||||
value={clientId}
|
||||
onChange={(e) => setClientId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="nuance_secret">
|
||||
Secret<span>*</span>
|
||||
</label>
|
||||
<Passwd
|
||||
id="nuance_secret"
|
||||
required
|
||||
name="nuance_secret"
|
||||
placeholder="Secret Key"
|
||||
value={secretKey ? getObscuredSecret(secretKey) : secretKey}
|
||||
onChange={(e) => setSecretKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</fieldset>
|
||||
<>
|
||||
<fieldset>
|
||||
<label htmlFor="nuance_client_id">
|
||||
Client ID
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && (
|
||||
<span>*</span>
|
||||
)}
|
||||
</label>
|
||||
<input
|
||||
id="nuance_client_id"
|
||||
required={!onPremNuanceSttCheck && !onPremNuanceTtsCheck}
|
||||
type="text"
|
||||
name="nuance_client_id"
|
||||
placeholder="Client ID"
|
||||
value={clientId}
|
||||
onChange={(e) => setClientId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="nuance_secret">
|
||||
Secret
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && (
|
||||
<span>*</span>
|
||||
)}
|
||||
</label>
|
||||
<Passwd
|
||||
id="nuance_secret"
|
||||
required={!onPremNuanceSttCheck && !onPremNuanceTtsCheck}
|
||||
name="nuance_secret"
|
||||
placeholder="Secret Key"
|
||||
value={secretKey ? getObscuredSecret(secretKey) : secretKey}
|
||||
onChange={(e) => setSecretKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<>
|
||||
<Checkzone
|
||||
hidden
|
||||
name="on_prem_nuance_use_tts"
|
||||
label="Use on-prem TTS"
|
||||
initialCheck={initialOnPremNuanceTtsCheck}
|
||||
handleChecked={(e) => {
|
||||
setOnPremNuanceTtsCheck(e.target.checked);
|
||||
if (!e.target.checked) {
|
||||
setTmpOnPremNuanceTtsUrl(onPremNuanceTtsUrl);
|
||||
setOnPremNuanceTtsUrl("");
|
||||
} else {
|
||||
setOnPremNuanceTtsUrl(tmpOnPremNuanceTtsUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<label htmlFor="on_prem_nuance_use_tts">
|
||||
TTS URI<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="on_prem_nuance_use_tts"
|
||||
type="text"
|
||||
name="on_prem_nuance_use_tts"
|
||||
placeholder="ip:port"
|
||||
pattern="(.*):([0-9]{0,6}$)"
|
||||
required={onPremNuanceTtsCheck}
|
||||
value={onPremNuanceTtsUrl}
|
||||
onChange={(e) => {
|
||||
setOnPremNuanceTtsUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Checkzone>
|
||||
|
||||
<Checkzone
|
||||
hidden
|
||||
name="on_prem_nuance_use_stt"
|
||||
label="Use on-prem STT"
|
||||
initialCheck={initialOnPremNuanceSttCheck}
|
||||
handleChecked={(e) => {
|
||||
setOnPremNuanceSttCheck(e.target.checked);
|
||||
if (!e.target.checked) {
|
||||
setTmpOnPremNuanceSttUrl(onPremNuanceSttUrl);
|
||||
setOnPremNuanceSttUrl("");
|
||||
} else {
|
||||
setOnPremNuanceSttUrl(tmpOnPremNuanceSttUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<label htmlFor="on_prem_nuance_use_stt_lb">
|
||||
STT URI<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="on_prem_nuance_use_stt"
|
||||
type="text"
|
||||
name="on_prem_nuance_use_stt"
|
||||
placeholder="ip:port"
|
||||
pattern="(.*):([0-9]{0,6}$)"
|
||||
required={onPremNuanceSttCheck}
|
||||
value={onPremNuanceSttUrl}
|
||||
onChange={(e) => {
|
||||
setOnPremNuanceSttUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Checkzone>
|
||||
</>
|
||||
</fieldset>
|
||||
</>
|
||||
)}
|
||||
{vendor === VENDOR_AWS && (
|
||||
<fieldset>
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import React, { useContext } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { postLogin } from "src/api";
|
||||
import { postLogin, postLogout } from "src/api";
|
||||
import { StatusCodes } from "src/api/types";
|
||||
import {
|
||||
ROUTE_LOGIN,
|
||||
ROUTE_CREATE_PASSWORD,
|
||||
ROUTE_INTERNAL_ACCOUNTS,
|
||||
ROUTE_INTERNAL_APPLICATIONS,
|
||||
ROUTE_LOGIN,
|
||||
} from "./routes";
|
||||
import {
|
||||
SESS_OLD_PASSWORD,
|
||||
@@ -136,10 +136,27 @@ export const useProvideAuth = (): AuthStateContext => {
|
||||
};
|
||||
|
||||
const signout = () => {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
sessionStorage.setItem(SESS_FLASH_MSG, MSG_LOGGED_OUT);
|
||||
window.location.href = ROUTE_LOGIN;
|
||||
return new Promise((resolve, reject) => {
|
||||
postLogout()
|
||||
.then((response) => {
|
||||
if (response.status === StatusCodes.OK) {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
sessionStorage.setItem(SESS_FLASH_MSG, MSG_LOGGED_OUT);
|
||||
resolve(response.json);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
sessionStorage.setItem(SESS_FLASH_MSG, MSG_LOGGED_OUT);
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
reject(MSG_SOMETHING_WRONG);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user