diff --git a/jams-react-client/src/auth.js b/jams-react-client/src/auth.js index eae75c7b7b4e97929ba8508d4dd26c40c739fed4..16c40f0c4848a6029c385661fdbea78c1640a30b 100644 --- a/jams-react-client/src/auth.js +++ b/jams-react-client/src/auth.js @@ -1,229 +1,262 @@ import configApiCall from "api.js"; -import axios from 'axios'; - -import { - api_path_post_install_admin, - api_path_post_auth_login, - api_path_get_server_status, - api_path_get_install_lastKnownStep, - api_path_get_directories, - api_path_get_subscription_status, - api_path_get_needs_update +import axios from "axios"; + +import { + api_path_post_install_admin, + api_path_post_auth_login, + api_path_get_server_status, + api_path_get_install_lastKnownStep, + api_path_get_directories, + api_path_get_subscription_status, + api_path_get_needs_update, } from "globalUrls"; class Auth { - constructor() { - this.authenticated = false - this.admin = false - this.installed = false - this.uri = '' - this.username = '' - this.localVersion = '' - this.remoteVersion = '' - this.activated = false - this.updateAvailable = false - } - - setJWT(access_token) { - window.localStorage.removeItem('access_token'); - window.localStorage.setItem('access_token', access_token); - } + constructor() { + this.authenticated = false; + this.admin = false; + this.installed = false; + this.uri = ""; + this.username = ""; + this.localVersion = ""; + this.remoteVersion = ""; + this.activated = false; + this.updateAvailable = false; + } - setScope(scope) { - window.localStorage.removeItem('scope'); - window.localStorage.setItem('scope', scope); - } + setJWT(access_token) { + window.localStorage.removeItem("access_token"); + window.localStorage.setItem("access_token", access_token); + } - setLocalDirectory(localDirectory) { - window.localStorage.removeItem('localDirectory'); - window.localStorage.setItem('localDirectory', localDirectory); - } + setScope(scope) { + window.localStorage.removeItem("scope"); + window.localStorage.setItem("scope", scope); + } - deleteJWT(){ - window.localStorage.removeItem('access_token'); - } - - setUsername(username) { - window.localStorage.removeItem('username'); - window.localStorage.setItem('username', username); - } - - deleteUserhame() { - window.localStorage.removeItem('username'); - } + setLocalDirectory(localDirectory) { + window.localStorage.removeItem("localDirectory"); + window.localStorage.setItem("localDirectory", localDirectory); + } - login(jsonData, cb) { - this.deleteJWT() - axios(configApiCall(api_path_post_auth_login, "POST", jsonData, null)).then((response) => { - if(response.status === 200){ - this.setJWT(response.data['access_token']); - this.setScope(response.data["scope"] === "ADMIN" ? true : false); - this.setUsername(jsonData.username); - this.authenticated = true; - } - cb() - }).catch((error) => { - this.setJWT(""); - this.setUsername(""); - this.authenticated = false; - cb(error) - }); - } + deleteJWT() { + window.localStorage.removeItem("access_token"); + } - logout(cb) { - this.deleteJWT() - this.authenticated = false - this.deleteUserhame() - cb() - } + setUsername(username) { + window.localStorage.removeItem("username"); + window.localStorage.setItem("username", username); + } - isAuthenticated() { - return this.authenticated; - } + deleteUserhame() { + window.localStorage.removeItem("username"); + } - isLocalDirectory() { - return window.localStorage.getItem('localDirectory') === 'true' ? true : false; - } + login(jsonData, cb) { + this.deleteJWT(); + axios(configApiCall(api_path_post_auth_login, "POST", jsonData, null)) + .then((response) => { + if (response.status === 200) { + this.setJWT(response.data["access_token"]); + this.setScope(response.data["scope"] === "ADMIN" ? true : false); + this.setUsername(jsonData.username); + this.authenticated = true; + } + cb(); + }) + .catch((error) => { + this.setJWT(""); + this.setUsername(""); + this.authenticated = false; + cb(error); + }); + } - checkDirectoryType(cb){ - axios(configApiCall(api_path_get_directories, "GET", null, null)).then((response) => { - if (response.data.length === 1) { - this.setLocalDirectory(true); - } - else if (response.data.length === 2){ - this.setLocalDirectory(false); - }else{ - console.log("Error getting on checkDirectoryType: Size of directory types is " + response.data.length); - } - cb() - }).catch((error) => { - console.log("Error getting on checkDirectoryType: " + error); - cb() - }); - } + logout(cb) { + this.deleteJWT(); + this.authenticated = false; + this.deleteUserhame(); + cb(); + } - checkAdminAccountStatus(cb) { - axios(configApiCall(api_path_post_install_admin, "GET", null, null)).then((response) => { - if (response['headers']['showlogin'] === "true") { - this.admin = true; - } - cb() - }).catch((error) => { - if(error.response.status === 404){ - this.admin = true; - } - else{ - console.log("Error during API request on checkAdminAccountStatus: " + error); - } - cb() - }); - } + isAuthenticated() { + return this.authenticated; + } - checkServerInstalled(cb) { - axios(configApiCall(api_path_get_server_status, "GET", null, null)).then((response) => { - if (response.data['installed'] === 'true') { - this.installed = true - console.log("Server is installed") - } else { - this.installed = false - console.log("Server is not installed") - } - cb() - }).catch((error) => { - if (error.response.status === 401) { - this.authenticated = false; - } - }); - } + isLocalDirectory() { + return window.localStorage.getItem("localDirectory") === "true" + ? true + : false; + } - checkLastKnownStep(cb) { - if(this.installed){ - this.authenticated = true - cb() - }else{ - axios(configApiCall(api_path_get_install_lastKnownStep, 'GET', null, null)).then((response) => { - this.uri = response.data['uri']; - this.authenticated = true; - cb() - }).catch((error) => { - if(error.response.status === 401){ - this.authenticated = false; - } - cb() - }) + checkDirectoryType(cb) { + axios(configApiCall(api_path_get_directories, "GET", null, null)) + .then((response) => { + if (response.data.length === 1) { + this.setLocalDirectory(true); + } else if (response.data.length === 2) { + this.setLocalDirectory(false); + } else { + console.log( + "Error getting on checkDirectoryType: Size of directory types is " + + response.data.length + ); } - } + cb(); + }) + .catch((error) => { + console.log("Error getting on checkDirectoryType: " + error); + cb(); + }); + } - checkForUpdates(cb) { - if (this.installed && this.authenticated) { - axios(configApiCall(api_path_get_subscription_status, 'GET', null, null)).then((response) => { - this.activated = response.data['activated']; - cb() - }) + checkAdminAccountStatus(cb) { + axios(configApiCall(api_path_post_install_admin, "GET", null, null)) + .then((response) => { + if (response["headers"]["showlogin"] === "true") { + this.admin = true; + } + cb(); + }) + .catch((error) => { + if (error.response.status === 404) { + this.admin = true; } else { - axios(configApiCall(api_path_get_install_lastKnownStep, 'GET', null, null)).then((response) => { - this.uri = response.data['uri'] - this.authenticated = true - cb() - }).catch((error) => { - cb() - }) + console.log( + "Error during API request on checkAdminAccountStatus: " + error + ); } - } + cb(); + }); + } - getUpdates(cb) { - if (this.installed && this.authenticated) { - axios(configApiCall(api_path_get_needs_update, 'GET', null, null)).then((response) => { - this.remoteVersion = response.data['remoteVersions']['jams-server.jar']['version']; - this.updateAvailable = response.data['updateAvailable']; - cb() - }) + checkServerInstalled(cb) { + axios(configApiCall(api_path_get_server_status, "GET", null, null)) + .then((response) => { + if (response.data["installed"] === "true") { + this.installed = true; + console.log("Server is installed"); } else { - axios(configApiCall(api_path_get_install_lastKnownStep, 'GET', null, null)).then((response) => { - this.uri = response.data['uri'] - this.authenticated = true - cb() - }).catch((error) => { - cb() - }) + this.installed = false; + console.log("Server is not installed"); } - } + cb(); + }) + .catch((error) => { + if (error.response.status === 401) { + this.authenticated = false; + } + }); + } - isActivated() { - return this.activated; + checkLastKnownStep(cb) { + if (this.installed) { + this.authenticated = true; + cb(); + } else { + axios( + configApiCall(api_path_get_install_lastKnownStep, "GET", null, null) + ) + .then((response) => { + this.uri = response.data["uri"]; + this.authenticated = true; + cb(); + }) + .catch((error) => { + if (error.response.status === 401) { + this.authenticated = false; + } + cb(); + }); } + } - isServerInstalled() { - return this.installed; + checkForUpdates(cb) { + if (this.installed && this.authenticated) { + axios( + configApiCall(api_path_get_subscription_status, "GET", null, null) + ).then((response) => { + this.activated = response.data["activated"]; + cb(); + }); + } else { + axios( + configApiCall(api_path_get_install_lastKnownStep, "GET", null, null) + ) + .then((response) => { + this.uri = response.data["uri"]; + this.authenticated = true; + cb(); + }) + .catch((error) => { + cb(); + }); } + } - isUpdateAvailable() { - return this.updateAvailable; + getUpdates(cb) { + if (this.installed && this.authenticated) { + axios(configApiCall(api_path_get_needs_update, "GET", null, null)).then( + (response) => { + if (response.data["updateAvailable"]) { + this.remoteVersion = + response.data["remoteVersions"]["jams-server.jar"]["version"]; + } else { + this.updateAvailable = false; + } + cb(); + } + ); + } else { + axios( + configApiCall(api_path_get_install_lastKnownStep, "GET", null, null) + ) + .then((response) => { + this.uri = response.data["uri"]; + this.authenticated = true; + cb(); + }) + .catch((error) => { + cb(); + }); } + } - getLocalVersion() { - return this.localVersion; - } + isActivated() { + return this.activated; + } - getRemoteVersion() { - return this.remoteVersion; - } + isServerInstalled() { + return this.installed; + } - hasAdmin() { - return this.admin; - } + isUpdateAvailable() { + return this.updateAvailable; + } - hasAdminScope(){ - return window.localStorage.getItem('scope') === 'true' ? true : false; - } + getLocalVersion() { + return this.localVersion; + } - getUsername(){ - return window.localStorage.getItem('username'); - } + getRemoteVersion() { + return this.remoteVersion; + } - isInstalled() { - return this.installed; - } + hasAdmin() { + return this.admin; + } + + hasAdminScope() { + return window.localStorage.getItem("scope") === "true" ? true : false; + } + + getUsername() { + return window.localStorage.getItem("username"); + } + + isInstalled() { + return this.installed; + } } -export default new Auth() \ No newline at end of file +export default new Auth(); diff --git a/jams-react-client/src/views/Contacts/Contacts.js b/jams-react-client/src/views/Contacts/Contacts.js index c85e1af899512bcfad5038c1d97c07e3522c7d14..579ee4b4147e4c8a8f9a4e43e94da47a79b49712 100644 --- a/jams-react-client/src/views/Contacts/Contacts.js +++ b/jams-react-client/src/views/Contacts/Contacts.js @@ -15,6 +15,7 @@ import CardFooter from "components/Card/CardFooter.js"; import BusinessOutlinedIcon from "@material-ui/icons/BusinessOutlined"; import QuestionAnswerIcon from "@material-ui/icons/QuestionAnswer"; import SmsFailedIcon from "@material-ui/icons/SmsFailed"; +import LaunchIcon from "@material-ui/icons/Launch"; import Search from "@material-ui/icons/Search"; import IconButton from "@material-ui/core/IconButton"; @@ -29,7 +30,7 @@ import { api_path_delete_admin_contacts, api_path_get_ns_name_from_addr, api_path_get_user_profile, - api_path_get_user_directory_search + api_path_get_user_directory_search, } from "globalUrls"; import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; @@ -77,7 +78,7 @@ const styles = { }, actionButtons: { height: "3em", - } + }, }; const useStyles = makeStyles(styles); @@ -108,15 +109,15 @@ export default function Users(props) { .then((response) => { let profiles = []; const profilesResults = response.data.profiles; - profilesResults.forEach((profile) =>{ - if(profile.username !== props.username) { + profilesResults.forEach((profile) => { + if (profile.username !== props.username) { let existingContact = false; - contacts.forEach((contact)=>{ - if(profile.username === contact.username) existingContact = true; - }) - if(!existingContact) profiles.push(profile); + contacts.forEach((contact) => { + if (profile.username === contact.username) existingContact = true; + }); + if (!existingContact) profiles.push(profile); } - }) + }); setUsers(profiles); }) .catch((error) => { @@ -124,14 +125,13 @@ export default function Users(props) { if (error.response.status === 401) { auth.authenticated = false; history.push("/signin"); - }else if(error.response.status === 403){ + } else if (error.response.status === 403) { setAllowedToAdd(false); } }); - } + }; const getAllContacts = () => { - if (auth.hasAdminScope()) { axios( configApiCall( @@ -227,7 +227,6 @@ export default function Users(props) { }; const addContactToUser = (value) => { - const data = { owner: props.username, uri: value.id, @@ -335,12 +334,12 @@ export default function Users(props) { return ( <div> - <TemporaryDrawer - openDrawer={openDrawer} - setOpenDrawer={setOpenDrawer} - direction="right" + <TemporaryDrawer + openDrawer={openDrawer} + setOpenDrawer={setOpenDrawer} + direction="right" placeholder={i18next.t("add_contact", "Add contact…")} - searchTargets={searchContacts} + searchTargets={searchContacts} targets={users} existingTargets={contacts} addElementToTarget={addContactToUser} @@ -353,17 +352,22 @@ export default function Users(props) { aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > - <DialogTitle id="alert-dialog-title">{i18next.t("remove_contact", "Remove contact")}</DialogTitle> + <DialogTitle id="alert-dialog-title"> + {i18next.t("remove_contact", "Remove contact")} + </DialogTitle> <DialogContent> <DialogContentText id="alert-dialog-description"> - {i18next.t("are_you_sure_you_want_to_remove", "Are you sure you want to remove")} - <strong>{removedContactName}</strong> {i18next.t("from", "from")} {props.username} {i18next.t("contacts", "contacts")}{" "} - ? + {i18next.t( + "are_you_sure_you_want_to_remove", + "Are you sure you want to remove" + )} + <strong>{removedContactName}</strong> {i18next.t("from", "from")}{" "} + {props.username} {i18next.t("contacts", "contacts")} ? </DialogContentText> </DialogContent> <DialogActions> <Button onClick={() => setOpen(false)} color="primary"> - {i18next.t("cancel", "Cancel")} + {i18next.t("cancel", "Cancel")} </Button> <Button onClick={removeContact} color="info" autoFocus> {i18next.t("remove", "Remove")} @@ -373,16 +377,19 @@ export default function Users(props) { <GridContainer> <GridItem xs={12} sm={12} md={12}> <div className={classes.actionButtons}> - {allowedToAdd && <Button - variant="contained" - color="primary" - href="#contained-buttons" - onClick={() => { - setOpenDrawer(true); - }} - > - <AddCircleOutlineIcon /> {i18next.t("add_a_contact", "Add contact")} - </Button>} + {allowedToAdd && ( + <Button + variant="contained" + color="primary" + href="#contained-buttons" + onClick={() => { + setOpenDrawer(true); + }} + > + <AddCircleOutlineIcon />{" "} + {i18next.t("add_a_contact", "Add contact")} + </Button> + )} </div> <div className={classes.searchWrapper}> <CustomInput @@ -390,7 +397,10 @@ export default function Users(props) { className: classes.margin + " " + classes.search, }} inputProps={{ - placeholder: i18next.t("search_contacts_using", "Search contact fields (URI, firstname, lastname)"), + placeholder: i18next.t( + "search_contacts_using", + "Search contact fields (URI, firstname, lastname)" + ), inputProps: { "aria-label": i18next.t("search_contacts", "Search contacts"), }, @@ -409,13 +419,25 @@ export default function Users(props) { .filter((data) => { if (searchValue === null) return data; else { - if(typeof data.name !== "undefined" && typeof data.firstName !== "undefined" && typeof data.lastName !== "undefined" && typeof data.uri !== "undefined"){ - return data.name.toLowerCase().includes(searchValue.toLowerCase()) || data.firstName.toLowerCase().includes(searchValue.toLowerCase()) || data.lastName.toLowerCase().includes(searchValue.toLowerCase()) || data.uri.toLowerCase().includes(searchValue.toLowerCase()); - } - else { + if ( + typeof data.name !== "undefined" && + typeof data.firstName !== "undefined" && + typeof data.lastName !== "undefined" && + typeof data.uri !== "undefined" + ) { + return ( + data.name.toLowerCase().includes(searchValue.toLowerCase()) || + data.firstName + .toLowerCase() + .includes(searchValue.toLowerCase()) || + data.lastName + .toLowerCase() + .includes(searchValue.toLowerCase()) || + data.uri.toLowerCase().includes(searchValue.toLowerCase()) + ); + } else { return data; } - } }) .map((contact) => ( @@ -427,8 +449,8 @@ export default function Users(props) { key={contact.uri} style={{ display: contact.display }} > - {contact.username && <Card profile> - <a href={`/user/${contact.username}`}> + {contact.username && ( + <Card profile> <CardBody profile> <CardAvatar profile> <img @@ -440,39 +462,61 @@ export default function Users(props) { alt="..." /> </CardAvatar> + <a + style={{ float: "right", top: 0 }} + href={`/user/${contact.username}`} + > + <LaunchIcon + fontSize="small" + style={{ + marginRight: "10px", + color: "black", + }} + ></LaunchIcon> + </a> <h4 className={classes.cardTitle}> - {(contact.firstName || contact.lastName) &&`${contact.firstName} ${contact.lastName}`} + {(contact.firstName || contact.lastName) && + `${contact.firstName} ${contact.lastName}`} </h4> <ul> - <li> - {contact.username && <img - src={jami} - width="20" - alt="Jami" - style={{ marginRight: "10px" }} - />} + <li style={{ display: "block" }}> + {contact.username && ( + <img + src={jami} + width="20" + alt="Jami" + style={{ marginRight: "10px" }} + /> + )} {contact.username && ` ${contact.username}`} </li> - <li> - {contact.organization && <BusinessOutlinedIcon - fontSize="small" - style={{ marginRight: "10px" }} - />} + <li style={{ display: "block" }}> + {contact.organization && ( + <BusinessOutlinedIcon + fontSize="small" + style={{ marginRight: "10px" }} + /> + )} {contact.organization && ` ${contact.organization}`} </li> - <li> - { contact.conversationId === null ? <SmsFailedIcon - fontSize="small" - style={{ marginRight: "10px" }} - ></SmsFailedIcon> : <QuestionAnswerIcon - fontSize="small" - style={{ marginRight: "10px" }} - />} - {contact.conversationId === null ? "No conversation id" : ` ${contact.conversationId}`} + <li style={{ display: "block" }}> + {contact.conversationId === null ? ( + <SmsFailedIcon + fontSize="small" + style={{ marginRight: "10px" }} + ></SmsFailedIcon> + ) : ( + <QuestionAnswerIcon + fontSize="small" + style={{ marginRight: "10px" }} + /> + )} + {contact.conversationId === "null" + ? "No conversation id" + : `Conversation id: ${contact.conversationId}`} </li> </ul> </CardBody> - </a> <CardFooter> <IconButton color="secondary" @@ -483,10 +527,12 @@ export default function Users(props) { <DeleteOutlineIcon /> </IconButton> </CardFooter> - </Card>} + </Card> + )} </GridItem> ))} - {contacts === [] && props.username + i18next.t("has_no_contacts", " has no contacts")} + {contacts === [] && + props.username + i18next.t("has_no_contacts", " has no contacts")} </GridContainer> </div> ); diff --git a/userguide/src/mkpdfs-mkdocs-plugin b/userguide/src/mkpdfs-mkdocs-plugin index 655bea6fd66933876e5b93bca63f430935aa6b5b..07c2164ab829656f1e08c7eebf4fe683011e9fa2 160000 --- a/userguide/src/mkpdfs-mkdocs-plugin +++ b/userguide/src/mkpdfs-mkdocs-plugin @@ -1 +1 @@ -Subproject commit 655bea6fd66933876e5b93bca63f430935aa6b5b +Subproject commit 07c2164ab829656f1e08c7eebf4fe683011e9fa2