diff --git a/Milestone - 2/DB Schema.pdf b/Milestone - 2/DB Schema.pdf new file mode 100644 index 0000000..ead157e Binary files /dev/null and b/Milestone - 2/DB Schema.pdf differ diff --git a/Milestone - 2/DB_classDiagram.jpg b/Milestone - 2/DB_classDiagram.jpg new file mode 100644 index 0000000..56f9d4b Binary files /dev/null and b/Milestone - 2/DB_classDiagram.jpg differ diff --git a/Milestone - 2/init.pdf b/Milestone - 2/init.pdf new file mode 100644 index 0000000..16a036d Binary files /dev/null and b/Milestone - 2/init.pdf differ diff --git a/Spring_Server/.gitignore b/Spring_Server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/Spring_Server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/Spring_Server/.mvn/wrapper/maven-wrapper.jar b/Spring_Server/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..cb28b0e Binary files /dev/null and b/Spring_Server/.mvn/wrapper/maven-wrapper.jar differ diff --git a/Spring_Server/.mvn/wrapper/maven-wrapper.properties b/Spring_Server/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..5f0536e --- /dev/null +++ b/Spring_Server/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/Spring_Server/TODO b/Spring_Server/TODO new file mode 100644 index 0000000..341847e --- /dev/null +++ b/Spring_Server/TODO @@ -0,0 +1,9 @@ + DONE - handle login of patient + Done - handle multiple webrtc clients + Done little - record, mapstruct learn + DONE - handle patient authentication and authorization' + - handleConnectForCounsellor here the cousellor token set is created new instead of checking if already exiasts or not that have to be cheked and then the token set needs to be updatded + DONE - Use the Roles model to set the role in the token and also use the same in authorization + Doing - Create an api for counsellor patient patient_history and senior Docktor + - handle senior doctor joining or listening + REST Everything is in react code \ No newline at end of file diff --git a/Spring_Server/assets/.DS_Store b/Spring_Server/assets/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/Spring_Server/assets/.DS_Store differ diff --git a/Spring_Server/assets/female_lady.png b/Spring_Server/assets/female_lady.png new file mode 100644 index 0000000..e5f3b31 Binary files /dev/null and b/Spring_Server/assets/female_lady.png differ diff --git a/Spring_Server/assets/images/doctor-1.png b/Spring_Server/assets/images/doctor-1.png new file mode 100644 index 0000000..61a70ce Binary files /dev/null and b/Spring_Server/assets/images/doctor-1.png differ diff --git a/Spring_Server/assets/images/doctor-2.png b/Spring_Server/assets/images/doctor-2.png new file mode 100644 index 0000000..0841132 Binary files /dev/null and b/Spring_Server/assets/images/doctor-2.png differ diff --git a/Spring_Server/assets/images/doctor-3.png b/Spring_Server/assets/images/doctor-3.png new file mode 100644 index 0000000..d46e79e Binary files /dev/null and b/Spring_Server/assets/images/doctor-3.png differ diff --git a/Spring_Server/assets/photo-300kb.jpg b/Spring_Server/assets/photo-300kb.jpg new file mode 100644 index 0000000..462a5ad Binary files /dev/null and b/Spring_Server/assets/photo-300kb.jpg differ diff --git a/Spring_Server/keystore.p12 b/Spring_Server/keystore.p12 new file mode 100644 index 0000000..9aa4e2f Binary files /dev/null and b/Spring_Server/keystore.p12 differ diff --git a/Spring_Server/mvnw b/Spring_Server/mvnw new file mode 100644 index 0000000..66df285 --- /dev/null +++ b/Spring_Server/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/Spring_Server/mvnw.cmd b/Spring_Server/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/Spring_Server/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/Spring_Server/pom.xml b/Spring_Server/pom.xml new file mode 100644 index 0000000..034aba8 --- /dev/null +++ b/Spring_Server/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.2 + + + com.drvolte + Spring_Server + 0.0.1-SNAPSHOT + Spring_Server + Spring_Server + + 21 + + + + + org.springframework.boot + spring-boot-starter-data-rest + 3.2.4 + + + + org.springframework.boot + spring-boot-starter-mail + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-websocket + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.auth0 + java-jwt + 4.3.0 + + + org.projectlombok + lombok + 1.18.30 + provided + + + org.mapstruct + mapstruct + 1.5.5.Final + + + org.mapstruct + mapstruct-processor + 1.5.5.Final + + + org.springframework.boot + spring-boot-devtools + 3.2.3 + + + org.json + json + 20240205 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/Spring_Server/production/SQL-Scripts.sql b/Spring_Server/production/SQL-Scripts.sql new file mode 100644 index 0000000..27ea7c0 --- /dev/null +++ b/Spring_Server/production/SQL-Scripts.sql @@ -0,0 +1,67 @@ +use drvolte; + + +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(1, '1999-01-22', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. Hemant Kumar', '/assets/images/doctor-1.png', 'MD', 'Dermatologist', 'Hemant.Kumar@kmc.co.in', '["Hindi", "English", "Konkani"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(2, '1995-12-31', 'Survey no 45/2, ward. 150, Marathahalli - Sarjapur Rd, opposite Iblur, Ambalipura, Bellandur, Bengaluru, Karnataka 560102', 'Columbia Asia', 'Dr. Gururaj Otageri', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ_v4Yv8p9wFgOBre0NMW93paKEEMZO8tG2chNlJQqnhA&s', 'MBBS', 'Cardiologist', 'Gururaj.Otageri@columasia.co.in', '["Hindi", "English", "Kannada"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(3, '2000-10-31', 'x-700, crazy street, near mining office, purena, amlidhi, Raipur, Chhattisgarh 492001', 'Columbia Asia', 'Dr. Somesh Awasthi', '/assets/images/doctor-3.png', 'MD', 'Neurologist', 'Somesh.Awasthi@columasia.co.in', '["Hindi", "English", "Sanskrit"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(4, '2001-05-01', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. Karndevsinh Zala', '/assets/images/doctor-3.png', 'MBBS', 'Mental Orthopedics', 'Karn.Zala@columasia.co.in', '["Hindi", "English", "Gujarati"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(5, '1994-06-16', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Varun Shetty', '/assets/images/doctor-3.png', 'MD', 'Neurology', 'Varun.Shetty@columasia.co.in', '["Hindi", "English", "Tulu"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(6, '1993-07-20', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Nikhil Joshi', '/assets/images/doctor-3.png', 'MD', 'Pediatrics', 'Nikhil.Joshi@columasia.co.in', '["Hindi", "English", "Marathi"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(7, '1995-12-30', 'Survey no 45/2, ward. 150, Marathahalli - Sarjapur Rd, opposite Iblur, Ambalipura, Bellandur, Bengaluru, Karnataka 560102', 'Columbia Asia', 'Dr. mike lit', '/assets/images/doctor-2.png', 'MBBS', 'Urologist', 'mikelit@columasia.co.in', '["Hindi", "English", "Tamil"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(8, '2000-10-26', 'x-700, crazy street, near mining office, purena, amlidhi, Raipur, Chhattisgarh 492001', 'Columbia Asia', 'Dr. john cena', '/assets/images/doctor-3.png', 'MD', 'Nephrologist', 'u.cant.c.me@columasia.co.in', '["Hindi", "English", "Sanskrit"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(9, '2001-05-05', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. seedhe maut', '/assets/images/doctor-3.png', 'MBBS', 'Orthodontist', 'seedhe.maut@columasia.co.in', '["Hindi", "English", "Telugu"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(10, '2000-05-21', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. life sober', '/assets/images/doctor-3.png', 'MD', 'Oncologist', 'life.sober@columasia.co.in', '["Hindi", "English", "Tamil"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(11, '2001-05-05', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. Dre', '/assets/images/doctor-3.png', 'MBBS', 'Orthodontist', 'dre@columasia.co.in', '["Hindi", "English", "Dogri"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(12, '2000-05-21', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. Hook', '/assets/images/doctor-3.png', 'MD', 'Oncologist', 'hook@columasia.co.in', '["Hindi", "English", "Dogri"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(13, '2000-05-01', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. yukta peda', '/assets/images/doctor-3.png', 'MD', 'Anesthesiologist', 'peda.Zala@columasia.co.in', '["Hindi", "English", "Telugu"]', "enabled"); +insert into doctor (id, dob, hospital_address, hospital_name, name, profile_photo, qualification, specialization, email, languagues, status) values(14, '1999-01-23', '16/6, Millers Rd, Kaverappa Layout, Vasanth Nagar, Bengaluru, Karnataka 560052', 'KMC', 'Dr. Hemlata Kumari', '/assets/images/doctor-1.png', 'MD', 'Radiologist', 'HemlataKumari@kmc.co.in', '["Hindi", "English", "Telugu"]', "enabled"); + + +insert into counsellor values(1); +insert into counsellor values(2); +insert into counsellor values(3); +insert into counsellor values(4); +insert into counsellor values(13); +insert into counsellor values(14); +insert into counsellor values(7); +insert into counsellor values(8); +insert into counsellor values(9); +insert into counsellor values(10); +insert into counsellor values(11); +insert into counsellor values(12); + +insert into senior_dr values(5); +insert into senior_dr values(6); + + +insert into patient (id, allergies, blood_group, dob, languague, location, major_issues, minor_issues, name, ph_no, state) values(1, 'nil', 'AB-', '23 Jan 1952', 'English', 'Bengaluru', 'Heart related issues', 'Blood Pressure, Cholestrol', 'Donald Trump', '7019273903', 'Karnataka'); +insert into patient (id, allergies, blood_group, dob, languague, location, major_issues, minor_issues, name, ph_no, state) values(2, 'nil', 'O-', '23 Jan 1949', 'English', 'Mumbai', 'Neurological Disorders', 'Blood Pressure', 'Joe Biden', '9845323134', 'Maharashtra'); +insert into patient (id, allergies, blood_group, dob, languague, location, major_issues, minor_issues, name, ph_no, state) values(3, 'Nut Allergy, Dust Allergy', 'O+', '19 May 1981', 'English', 'Hyderabad', 'nil', 'Blood Pressure', 'Vivek Ramaswamy', '9738523214', 'Telangana'); +insert into patient (id, allergies, blood_group, dob, languague, location, major_issues, minor_issues, name, ph_no, state) values(4, 'Nut Allergy, Dust Allergy', 'O+', '01 Aug 1972', 'English', 'Kolkata', 'Mental Health Disorders', 'Blood Pressure', 'Barack Obama', '7019273903', 'West Bengal'); + + +insert into callback (id, followup_reason, schedule, counsellor_id, status, patient_id) values(1, "Followup callback to see how the patient is responding to the treatment", '2024-04-30 12:00:00.000000', 1, "complete", 1); +insert into callback (id, followup_reason, schedule, counsellor_id, status, patient_id) values(2, "Followup callback to see how the patient is responding to the prescribed medicine", '2024-10-01 12:00:00.000000', 2, "missed",2); +insert into callback (id, followup_reason, schedule, counsellor_id, status, patient_id) values(3, "Followup callback for the patients routine checkup.", '2024-04-15 12:00:00.000000', 3, "scheduled",3); +insert into callback (id, followup_reason, schedule, counsellor_id, status, patient_id) values(4, "Followup callback to see how the patient is responding to change in treatment", '2024-05-01 12:00:00.000000', 4, "complete",4); + + +insert into call_history(id, call_end, call_start, counsellor_id, patient_id, status) values(1, '2024-04-01 12:00:00.000000', '2024-04-01 11:30:00.000000', 1, 1,"complete"); +insert into call_history(id, call_end, call_start, counsellor_id, patient_id, status) values(2, '2024-04-02 11:30:00.000000', '2024-04-01 10:30:00.000000', 2, 2, "missed"); +insert into call_history(id, call_end, call_start, counsellor_id, patient_id, status) values(3, '2024-04-03 14:30:00.000000', '2024-04-01 14:00:00.000000', 3, 3, "complete"); +insert into call_history(id, call_end, call_start, counsellor_id, patient_id, status) values(4, '2024-04-04 17:00:00.000000', '2024-04-01 16:40:00.000000', 4, 4, "missed"); + + +insert into patient_history (id, audio_recording, consent, created, prescription, summanry, symptoms, patient_id) values(1, '/assets/recordings/recording-1.mp4', 1, '2024-04-01 11:30:00.000000', 'Beta Blockers - Metoprolol : 1 time every day for a month','The patient reported his first experience of chest discomfort. Although, it is too late to tell what caused this exactly, I have prescribed him Beta-blockers to do away with the pain for the time being.','Chest discomfort or pain that may feel like pressure, squeezing, fullness, or tightness.', 1); +insert into patient_history (id, audio_recording, consent, created, prescription, summanry, symptoms, patient_id) values(2, '/assets/recordings/recording-2.mp4', 1, '2024-04-02 10:30:00.000000', 'Dopamine agonists - Pramipexole : 1 time every day for 6 months, COMT inhibitors - Entacapone : 2 times a day every day for 6 months','The patient is showing early signs of Parkinsons Disease. Suggested COMT inhibitors to manage the motor symptoms and Dopamine agonists to do away with the pain. Will monitor patient condition over the course of 6 months','Tremors, stiffness, bradykinesia (slowness of movement), postural instability, difficulty with balance and coordination.', 2); +insert into patient_history (id, audio_recording, consent, created, prescription, summanry, symptoms, patient_id) values(3, '/assets/recordings/recording-3.mp4', 1, '2024-04-03 14:00:00.000000', 'nil','Patient is experiencing severe tooth pain and we are now proceeding for a root canal treatment','Patient has lost a tooth', 3); +insert into patient_history (id, audio_recording, consent, created, prescription, summanry, symptoms, patient_id) values(4, '/assets/recordings/recording-4.mp4', 0, '2024-04-03 16:40:00.000000', 'Benzodiazepines : 2 times a day for 1 month, Selective serotonin reuptake inhibitors (SSRIs) - Escitalopram : 2 times a day for 1 month','Patient is experiencing severe degree of anxiety disorder based symptoms and has been ordered to take the prescribed treatment to provide short term relief and several other hormone uptake inhibhitors.','Excessive worry or fear, restlessness, irritability, muscle tension, difficulty concentrating, sleep disturbances, panic attacks (sudden onset of intense fear or discomfort).', 4); + + +insert into users (id, enable, name, password, role, username) values (1, 1, 'Hemant Kumar', 'hemant', 6, 'hemant'); +insert into users (id, enable, name, password, role, username) values (2, 1, 'Gururaj Otageri', 'guru', 4, 'guru'); +insert into users (id, enable, name, password, role, username) values (3, 1, 'Somesh Awasthi', 'somesh', 7, 'somesh'); +insert into users (id, enable, name, password, role, username) values (4, 1, 'Karndevsinh Zala', 'karn', 4, 'karn'); +insert into users (id, enable, name, password, role, username) values (5, 1, 'Varun Shetty', 'varun', 6, 'varun'); +insert into users (id, enable, name, password, role, username) values (6, 1, 'Nikhil Joshi', 'nikhil', 6, 'Nikhil'); +insert into users (id, enable, name, password, role, username) values (7, 1, 'Someone', 'admin', 7, 'admin@drvolte'); \ No newline at end of file diff --git a/Spring_Server/production/Spring_Server-0.0.1-SNAPSHOT.jar b/Spring_Server/production/Spring_Server-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..c70befc Binary files /dev/null and b/Spring_Server/production/Spring_Server-0.0.1-SNAPSHOT.jar differ diff --git a/Spring_Server/production/keystore.p12 b/Spring_Server/production/keystore.p12 new file mode 100644 index 0000000..9aa4e2f Binary files /dev/null and b/Spring_Server/production/keystore.p12 differ diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/SpringServerApplication.java b/Spring_Server/src/main/java/com/drvolte/spring_server/SpringServerApplication.java new file mode 100644 index 0000000..8c88db7 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/SpringServerApplication.java @@ -0,0 +1,60 @@ +package com.drvolte.spring_server; + +import org.apache.catalina.connector.Connector; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class SpringServerApplication { + + @Value("${http.port}") + private int httpPort; + + public static void main(String[] args) { + + if (args.length == 2) { + + // Extract MySQL username and password from command line arguments + String username = args[0]; + String password = args[1]; + + // Set MySQL username and password as system properties + System.setProperty("spring.datasource.username", username); + System.setProperty("spring.datasource.password", password); + + } else if (args.length == 3) { + + // Extract MySQL username and password from command line arguments + String username = args[0]; + String password = args[1]; + String IP = args[2]; + + // Set MySQL username and password as system properties + System.setProperty("spring.datasource.username", username); + System.setProperty("spring.datasource.password", password); + System.setProperty("server.address", IP); + + } else { + System.out.println("Usage: java -jar application.jar "); + } + + SpringApplication.run(SpringServerApplication.class, args); + } + + @Bean + public ServletWebServerFactory servletContainer() { + TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); + tomcat.addAdditionalTomcatConnectors(createStandardConnector()); + return tomcat; + } + + private Connector createStandardConnector() { + Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); + connector.setPort(httpPort); + return connector; + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/CorsPolicy.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/CorsPolicy.java new file mode 100644 index 0000000..42a1936 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/CorsPolicy.java @@ -0,0 +1,23 @@ +package com.drvolte.spring_server.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + + +@Configuration +public class CorsPolicy { + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/JwtAuthFilter.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/JwtAuthFilter.java new file mode 100644 index 0000000..587fea7 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/JwtAuthFilter.java @@ -0,0 +1,49 @@ +package com.drvolte.spring_server.config; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Configuration +public class JwtAuthFilter extends OncePerRequestFilter { + + + private static final Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class); + private final UserAuthenticationProvider userAuthProvider; + + + public JwtAuthFilter(UserAuthenticationProvider userAuthProvider) { + this.userAuthProvider = userAuthProvider; + } + + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String header = request.getHeader(HttpHeaders.AUTHORIZATION); + logger.info(request.getRequestURL().toString() + " from " + request.getRemoteAddr()); + String remoteAddr = request.getRemoteAddr(); + Integer remotePort = request.getRemotePort(); + if (header != null) { + String[] authELements = header.split(" "); + if (authELements.length == 2 && authELements[0].equals("Bearer")) { + try { + SecurityContextHolder.getContext().setAuthentication(this.userAuthProvider.validateToken(authELements[1], remoteAddr, remotePort)); + + } catch (RuntimeException e) { + SecurityContextHolder.clearContext(); + throw e; + } + } + } + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/PasswordEncoderConfig.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/PasswordEncoderConfig.java new file mode 100644 index 0000000..f310cca --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/PasswordEncoderConfig.java @@ -0,0 +1,15 @@ +package com.drvolte.spring_server.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class PasswordEncoderConfig { + + @Bean + public PasswordEncoder passEncoder() { + return NoOpPasswordEncoder.getInstance(); + } +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/RestException.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/RestException.java new file mode 100644 index 0000000..ffe924a --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/RestException.java @@ -0,0 +1,18 @@ +package com.drvolte.spring_server.config; + +import com.drvolte.spring_server.dtos.ErrorDto; +import com.drvolte.spring_server.exceptions.AppException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class RestException { + @ExceptionHandler(value = {AppException.class}) + @ResponseBody + public ResponseEntity handleException(AppException ex) { + return ResponseEntity.status(ex.getHttpStatus()) + .body(new ErrorDto(ex.getMessage())); + } +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/UserAuthenticationProvider.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/UserAuthenticationProvider.java new file mode 100644 index 0000000..0ba6dd8 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/UserAuthenticationProvider.java @@ -0,0 +1,123 @@ +package com.drvolte.spring_server.config; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.drvolte.spring_server.dtos.PatientResponseDto; +import com.drvolte.spring_server.dtos.UserDto; +import jakarta.annotation.PostConstruct; +import lombok.Data; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.stereotype.Component; + +import java.util.Base64; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +@Component +@Data +public class UserAuthenticationProvider { + + private String secretKey = "SECRET"; + private Algorithm algorithm; + + private HashSet invalidTokens; + private JWTVerifier verifier; + + @PostConstruct + public void init() { + this.secretKey = Base64.getEncoder().encodeToString(this.secretKey.getBytes()); + this.algorithm = Algorithm.HMAC256(secretKey); + this.verifier = JWT.require(algorithm) + .build(); + this.invalidTokens = new HashSet(); + } + + public String createToken(UserDto user, String remoteAddr, Integer remotePort) { + Date now = new Date(); + Date validity = new Date(now.getTime() + 3600000 * 9); // 9 hour + + return JWT.create() + .withSubject(user.getUsername()) + .withClaim("id", user.getId()) + .withIssuedAt(now) + .withExpiresAt(validity) + .withClaim("firstName", user.getFirstName()) + .withClaim("addr", remoteAddr) + .withClaim("port", remotePort) + .withClaim("role", user.getRole()) + .sign(algorithm); + } + + public Authentication validateToken(String token, String remoteAddr, Integer remotePort) throws JWTVerificationException { + + + if (this.invalidTokens.contains("\"" + token + "\"")) { + System.out.println("inside if contains"); + throw new JWTVerificationException("Invalid token " + token); + } + DecodedJWT decoded = verifier.verify(token); + Set roles = new HashSet(); + roles.add(decoded.getClaim("role").asString()); + if (roles.contains("ROLE_PATIENT")) { + PatientResponseDto patientResponseDto = PatientResponseDto.builder() + .id(decoded.getClaim("id").asLong()) + .token(token) + .phnumber(decoded.getSubject()) + .role(decoded.getClaim("role").asString()) + .build(); + return new UsernamePasswordAuthenticationToken(patientResponseDto, null, AuthorityUtils.createAuthorityList(roles.toArray(new String[0]))); + } + String tokenAddr = decoded.getClaim("addr").asString(); + if (!tokenAddr.equals("Ignore") && !tokenAddr.equals(remoteAddr)) { + System.out.println(tokenAddr + " " + remoteAddr); + throw new JWTVerificationException("IP Address or Port illegal"); + } + + UserDto user = UserDto.builder() + .username(decoded.getSubject()) + .firstName(decoded.getClaim("firstName").asString()) + .lastName(decoded.getClaim("lastName").asString()) + .role(decoded.getClaim("role").asString()) + .build(); + System.out.println("roles::" + roles); + return new UsernamePasswordAuthenticationToken(user, null, AuthorityUtils.createAuthorityList(roles.toArray(new String[0]))); + } + + public DecodedJWT getDecoded(String token) throws JWTVerificationException { + if (this.invalidTokens.contains("\"" + token + "\"")) { + throw new JWTVerificationException("Invalid token " + token); + } + return verifier.verify(token); + } + + + public String createTokenForPatient(PatientResponseDto patientResponseDto) { + Date now = new Date(); + Date validity = new Date(now.getTime() + 3600000 * 9); // 1 hour + return JWT.create() + .withClaim("id", patientResponseDto.getId()) + .withIssuedAt(now) + .withExpiresAt(validity) + .withClaim("role", "ROLE_PATIENT") + .sign(algorithm); + } + + public String createTokenForEnrollDoctor(String email, String name, String role) { + Date now = new Date(); + Date validity = new Date(now.getTime() + 3600000); // 1 hour + return JWT.create() + .withClaim("name", name) + .withClaim("email", email) + .withClaim("role", role) + .withClaim("addr", "Ignore") + .withIssuedAt(now) + .withExpiresAt(validity) + .sign(algorithm); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/WebSocketConfig.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/WebSocketConfig.java new file mode 100644 index 0000000..fe0e592 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/WebSocketConfig.java @@ -0,0 +1,30 @@ +package com.drvolte.spring_server.config; + +import com.drvolte.spring_server.models.WebSocketConnection; +import com.drvolte.spring_server.service.WebSocketHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer { + + private final WebSocketConnection webSocketConnections; + private final UserAuthenticationProvider jwtAuthProvider; + + @Autowired + public WebSocketConfig(WebSocketConnection webSocketConnections, UserAuthenticationProvider jwtAuthProvider) { + this.webSocketConnections = webSocketConnections; + this.jwtAuthProvider = jwtAuthProvider; + } + + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + System.out.println("Adding a Websocket Handler"); + registry.addHandler(new WebSocketHandler(this.webSocketConnections, this.jwtAuthProvider), "/socket").setAllowedOrigins("*"); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/config/httpSecurityConfig.java b/Spring_Server/src/main/java/com/drvolte/spring_server/config/httpSecurityConfig.java new file mode 100644 index 0000000..2766272 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/config/httpSecurityConfig.java @@ -0,0 +1,54 @@ +package com.drvolte.spring_server.config; + +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.drvolte.spring_server.models.Roles; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class httpSecurityConfig { + + @Autowired + private UserAuthenticationProvider userAuthProvider; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + try { + http.csrf(AbstractHttpConfigurer::disable) + .addFilterBefore(new JwtAuthFilter(userAuthProvider), BasicAuthenticationFilter.class) + .sessionManagement(customizer -> customizer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests((requests) -> requests + .requestMatchers(HttpMethod.POST, "/login", "/patients_register", "/mail/send/*", "/logoutuser").permitAll() + .requestMatchers("/socket").permitAll() + .requestMatchers("/hello").hasAnyRole( + Roles.PATIENT.toString(), + Roles.COUNSELLOR.toString(), + Roles.ADMIN.toString(), + Roles.SENIORDR.toString() + ) + .requestMatchers("/mail/changePassword").hasAnyRole( + Roles.COUNSELLOR.toString(), + Roles.SENIORDR.toString() + ) + .requestMatchers("/counsellor/**").hasRole(Roles.COUNSELLOR.toString()) + .requestMatchers("/seniordr/**").hasRole(Roles.SENIORDR.toString()) + .requestMatchers("/patient/**").hasRole(Roles.PATIENT.toString()) + .requestMatchers("/patienthistory/**").hasRole(Roles.PATIENT.toString()) + .anyRequest().authenticated()); + } catch (JWTVerificationException e) { + System.out.println("Token Expired or invalid token or token used in invalidated"); + } catch (Exception e) { + System.out.println("Some Exception " + e); + } + return http.build(); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/controller/EmailController.java b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/EmailController.java new file mode 100644 index 0000000..1db3e96 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/EmailController.java @@ -0,0 +1,111 @@ +package com.drvolte.spring_server.controller; + +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.drvolte.spring_server.config.UserAuthenticationProvider; +import com.drvolte.spring_server.dao.CounsellorRepository; +import com.drvolte.spring_server.dao.SeniorDrRepository; +import com.drvolte.spring_server.dao.UserRepository; +import com.drvolte.spring_server.entity.Counsellor; +import com.drvolte.spring_server.entity.SeniorDr; +import com.drvolte.spring_server.entity.User; +import com.drvolte.spring_server.models.ChangePasswordStructure; +import com.drvolte.spring_server.models.EmailStructure; +import com.drvolte.spring_server.models.Roles; +import com.drvolte.spring_server.service.EmailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +@RestController +@RequestMapping("/mail") +public class EmailController { + + @Autowired + private EmailService emailService; + + @Autowired + private CounsellorRepository counsellorRepository; + + @Autowired + private SeniorDrRepository seniorDrRepository; + + @Autowired + private UserAuthenticationProvider userAuthProvider; + + @Autowired + private UserRepository userRepository; + + @PostMapping("/send/{mailId}") + public ResponseEntity sendMail(@PathVariable String mailId) { + EmailStructure emailStructure = new EmailStructure(); + + Optional seniorDoc = seniorDrRepository.findSeniorDrsByEmailOrQualificationOrSpecialization(mailId, "", "").stream().findFirst(); + Optional counsellorDoc = counsellorRepository.findCounsellorsByEmailOrQualificationOrSpecialization(mailId, "", "").stream().findFirst(); + + String role = ""; + String name = ""; + String doctor_status = ""; + if (seniorDoc.isEmpty() && counsellorDoc.isEmpty()) { + return ResponseEntity.ok("No doctor found with the given criteria !"); + } else { + if (seniorDoc.isPresent()) { + SeniorDr seniorDr = seniorDoc.get(); + name = seniorDr.getName(); + role = Roles.ROLE_SENIORDR.toString(); + doctor_status = seniorDr.getStatus(); + } else { + Counsellor counsellor = counsellorDoc.get(); + name = counsellor.getName(); + role = Roles.ROLE_COUNSELLOR.toString(); + doctor_status = counsellor.getStatus(); + } + } + if (doctor_status.equals("enabled")) { + // Doctor is enabled => Doctor is present in the Users table => Allow Doctor to reset his password ! + String token = ""; + token = userAuthProvider.createTokenForEnrollDoctor(mailId, name, role); + String ip = System.getProperty("server.address"); + emailStructure.setSubject("[Dr. Volte] Register Doctor"); + emailStructure.setMessage("Please click on the following link to create password and register yourself ! \n" + + "\nUse https://" + ip + ":3000/adminSignUpDoctor?token=" + token + + "\n\nRegards, \n Admin @ DrVolte"); + emailService.sendMail(mailId, emailStructure); + } + return ResponseEntity.ok("The email was sent successfully !"); + } + + @PostMapping("/changePassword") + public ResponseEntity changePassword(@RequestBody ChangePasswordStructure passwordStructure) { + String password = passwordStructure.getPassword(); + String token = passwordStructure.getToken(); + try { + DecodedJWT decodedJWT = userAuthProvider.getDecoded(token); + String name = decodedJWT.getClaim("name").asString(); + String email = decodedJWT.getClaim("email").asString(); + String role = decodedJWT.getClaim("role").asString(); + + Optional user = userRepository.findByUsername(email); + if (user.isPresent()) { + // The required user was found in the database + User oldUser = user.get(); + oldUser.setPassword(password); + userRepository.save(oldUser); + } else { + // User was not found, so we have to create a new user. + User newDoctor = new User(); + newDoctor.setName(name); + newDoctor.setEnable(true); + newDoctor.setPassword(password); + newDoctor.setRole(Roles.valueOf(role)); + newDoctor.setUsername(email); + userRepository.save(newDoctor); + } + } catch (JWTVerificationException e) { + System.out.println("Token has expired !" + e); + } + return ResponseEntity.ok("Password changed successfully !"); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/controller/FilesController.java b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/FilesController.java new file mode 100644 index 0000000..ab2ba18 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/FilesController.java @@ -0,0 +1,36 @@ +package com.drvolte.spring_server.controller; + +import com.drvolte.spring_server.dtos.FileUploadResponseDTO; +import com.drvolte.spring_server.service.FileStorageService; +import org.apache.coyote.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MaxUploadSizeExceededException; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +@RestController +@RequestMapping("/file") +public class FilesController { + + @Autowired + private FileStorageService fileStorageService; + + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity uploadPhoto(@RequestParam("image") MultipartFile file) throws IOException { + return fileStorageService.uploadImage(file); + } + + @GetMapping("/download") + public ResponseEntity downloadPhoto(@RequestParam("imagePath") String filePath) throws IOException + { + byte[] fileData = fileStorageService.downloadImage(filePath); + return ResponseEntity.status(HttpStatus.OK) + .contentType(MediaType.valueOf("image/png")) + .body(fileData); + } +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/controller/GeneralControllers.java b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/GeneralControllers.java new file mode 100644 index 0000000..ba71754 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/GeneralControllers.java @@ -0,0 +1,342 @@ +package com.drvolte.spring_server.controller; + +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.drvolte.spring_server.config.UserAuthenticationProvider; +import com.drvolte.spring_server.dao.DoctorRepository; +import com.drvolte.spring_server.dtos.CredentialsDto; +import com.drvolte.spring_server.dtos.UserDto; +import com.drvolte.spring_server.entity.Doctor; +import com.drvolte.spring_server.exceptions.AppException; +import com.drvolte.spring_server.models.Roles; +import com.drvolte.spring_server.models.WebSocketConnection; +import com.drvolte.spring_server.service.FileStorageService; +import com.drvolte.spring_server.service.UserService; +import jakarta.servlet.http.HttpServletRequest; +import org.json.JSONArray; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GeneralControllers { + + @Autowired + private final UserService userService; + @Autowired + private final UserAuthenticationProvider userAuthProvider; + + private final DoctorRepository doctorRepository; + + private final WebSocketConnection webSocketConnections; + private final UserAuthenticationProvider jwtAuthProvider; + + public GeneralControllers(UserService userService, UserAuthenticationProvider userAuthProvider, WebSocketConnection webSocketConnections, UserAuthenticationProvider jwtAuthProvider, FileStorageService storageServicee, DoctorRepository doctorRepository) { + this.userService = userService; + this.userAuthProvider = userAuthProvider; + this.webSocketConnections = webSocketConnections; + this.jwtAuthProvider = jwtAuthProvider; + this.doctorRepository = doctorRepository; + } + + @PostMapping("/login") + public ResponseEntity login(@RequestBody CredentialsDto credentialsdto, HttpServletRequest request) { + System.out.println(credentialsdto); + UserDto user = userService.login(credentialsdto); + + String remoteAddr = request.getRemoteAddr(); + Integer remotePort = request.getRemotePort(); + if (user.getRole().equals(Roles.ROLE_ADMIN.toString())) { + user.setToken(userAuthProvider.createToken(user, remoteAddr, remotePort)); + System.out.println("userdto from login " + user); + return ResponseEntity.ok(user); + } + Doctor doctor = doctorRepository.findByEmail(user.getUsername()).orElse(null); + if (doctor != null) { + System.out.println("Creating new Jwt with ip and port "); + user.setId(doctor.getId()); + user.setToken(userAuthProvider.createToken(user, remoteAddr, remotePort)); + System.out.println(user); + return ResponseEntity.ok(user); + } else { + System.out.println("username not found" + user); + throw new AppException("Username Not Found", HttpStatus.NOT_FOUND); + } + } + + @PostMapping("/logoutuser") + public ResponseEntity logout(@RequestBody String token) { + System.out.println("this is the token to invalidate " + token); + token = token.substring(1, token.length() - 1); + String sessionId = webSocketConnections.getTokenToSessionId().get(token); + webSocketConnections.getTokenToSessionId().remove(token); + webSocketConnections.getSessionIdToToken().remove(sessionId); + try { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Roles role = Roles.valueOf(decodedJWT.getClaim("role").asString()); + Long id = decodedJWT.getClaim("id").asLong(); + System.out.println(("this is the role and id for the token " + role + " " + id)); + for (String state : webSocketConnections.getRoleToStateToToken().get(role).keySet()) { + webSocketConnections.getRoleToStateToToken().get(role).get(state).remove(token); + } + + String counsellorToken, srDrToken, patientToken; + if (webSocketConnections.getTokenToRoleToToken().containsKey(token)) { + counsellorToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_COUNSELLOR, null); + srDrToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_SENIORDR, null); + patientToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_PATIENT, null); + webSocketConnections.getTokenToRoleToToken().remove(token); + System.out.println("removing the token from tokentoroletotoken for logout:" + patientToken + " \n" + counsellorToken + "\n" + srDrToken); + if (patientToken != null) + webSocketConnections.getTokenToRoleToToken().remove(patientToken); + if (counsellorToken != null) + webSocketConnections.getTokenToRoleToToken().remove(counsellorToken); + if (srDrToken != null) + webSocketConnections.getTokenToRoleToToken().remove(srDrToken); + } + webSocketConnections.getRoleToIdToToken().get(role).remove(id); + + } catch (JWTVerificationException ignored) { + System.out.println("Token validation erro"); + } + + jwtAuthProvider.getInvalidTokens().add(token); + return ResponseEntity.ok("Done"); + } + + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok("Hello brother"); + } + + + @GetMapping("/counsellor") + public ResponseEntity sayHelloconsellor() { + return ResponseEntity.ok("Hello brother counsellor"); + } + + + @GetMapping("/patient") + public ResponseEntity sayHellopatient() { + return ResponseEntity.ok("Hello brother patient"); + } + + @GetMapping("/onlinestatus") + public ResponseEntity getOnlineUsers() { + JSONObject retJson = new JSONObject() + .put(Roles.ROLE_COUNSELLOR + "_online", new JSONArray()) + .put(Roles.ROLE_SENIORDR + "_online", new JSONArray()) + .put(Roles.ROLE_COUNSELLOR + "_incall", new JSONArray()) + .put(Roles.ROLE_SENIORDR + "_incall", new JSONArray()) + .put(Roles.ROLE_COUNSELLOR + "_busy", new JSONArray()) + .put(Roles.ROLE_SENIORDR + "_busy", new JSONArray()) + .put(Roles.ROLE_PATIENT + "_online", new JSONArray()) + .put(Roles.ROLE_PATIENT + "_incall", new JSONArray()) + .put("inCallWaiting", new JSONArray()) + .put("missedCalls", new JSONArray()) + .put("counsellorCalls", new JSONObject()); + + //System.out.println("this the webscoketconenction setRoletostatetotoken value: " + // + webSocketConnections.getRoleToStateToToken()); + + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_COUNSELLOR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).containsKey("connected") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).get("connected")) { + // System.out.println(token); + try { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_COUNSELLOR + "_online").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No counsellor in online state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_COUNSELLOR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).containsKey("incall") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).get("incall")) { + // System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_COUNSELLOR + "_incall").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No counsellor in incall state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_SENIORDR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).containsKey("connected") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).get("connected")) { + // System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + System.out.println("this is the id from token " + id); + System.out.println(decodedJWT); + System.out.println(token); + retJson.getJSONArray(Roles.ROLE_SENIORDR + "_online").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + //System.out.println("No SR_DR in online state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_SENIORDR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).containsKey("incall") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).get("incall")) { + //System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_SENIORDR + "_incall").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No SE_DR in incall state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_SENIORDR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).containsKey("busy") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_SENIORDR).get("busy")) { + //System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_SENIORDR + "_busy").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No SE_DR in busy state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_PATIENT) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_PATIENT).containsKey("connected") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_PATIENT).get("connected")) { + // System.out.println(token); + try { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_PATIENT + "_online").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No patient in online state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_PATIENT) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_PATIENT).containsKey("incall") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_PATIENT).get("incall")) { + //System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_PATIENT + "_incall").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No patient in incall state" + webSocketConnections.getRoleToStateToToken()); + } + + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_COUNSELLOR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).containsKey("busy") + ) { + for (String token : webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).get("busy")) { + //System.out.println(token); + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Long id = decodedJWT.getClaim("id").asLong(); + retJson.getJSONArray(Roles.ROLE_COUNSELLOR + "_busy").put(id); + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + } else { + // System.out.println("No counsellor in busy state" + webSocketConnections.getRoleToStateToToken()); + } + + + for (String sourceToken : webSocketConnections.getTokenToRoleToToken().keySet()) { + try { + + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(sourceToken); + if (decodedJWT.getClaim("role").asString().equals(Roles.ROLE_COUNSELLOR.toString())) { + Long counsellorId = decodedJWT.getClaim("id").asLong(); + if (webSocketConnections.getTokenToRoleToToken().get(sourceToken).containsKey(Roles.ROLE_PATIENT)) { + String patientToken = webSocketConnections.getTokenToRoleToToken().get(sourceToken).get(Roles.ROLE_PATIENT); + DecodedJWT patientDecodedJWT = jwtAuthProvider.getDecoded(patientToken); + Long patientId = patientDecodedJWT.getClaim("id").asLong(); + retJson.getJSONObject("counsellorCalls").put(String.valueOf(counsellorId), patientId); + } + } + } catch (JWTVerificationException e) { + System.out.println("token is expired" + e); + } + } + + for (Long patientId : webSocketConnections.getWaitQueue()) { + retJson.getJSONArray("inCallWaiting").put(patientId); + } + for (Long patientId : webSocketConnections.getMissedCalls()) { + retJson.getJSONArray("missedCalls").put(patientId); + } + System.out.println("this is retjson:" + retJson); + // retJson.put("webSocketConnection", webSocketConnections); + return ResponseEntity + .ok() + .contentType(MediaType.APPLICATION_JSON) + .body(retJson.toString()); + } + + @GetMapping("/webSocketConnections") + public ResponseEntity getWebSocketConnections() { + JSONObject retJson = new JSONObject() + .put("tokenToSessionId", new JSONObject(webSocketConnections.getTokenToSessionId())) + .put("sessionIdToToken", new JSONObject(webSocketConnections.getSessionIdToToken())) + .put("roleToStateToToken", new JSONObject(webSocketConnections.getRoleToStateToToken())) + .put("tokenToRoleToToken", new JSONObject(webSocketConnections.getTokenToRoleToToken())) + .put("roleToIdToToken", new JSONObject(webSocketConnections.getRoleToIdToToken())) + .put("waitQueue", new JSONObject(webSocketConnections.getWaitQueue())) + .put("missedCalls", new JSONObject(webSocketConnections.getMissedCalls())); + return ResponseEntity + .ok() + .contentType(MediaType.APPLICATION_JSON) + .body(retJson.toString()); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientHistoryController.java b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientHistoryController.java new file mode 100644 index 0000000..da7bb86 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientHistoryController.java @@ -0,0 +1,37 @@ +package com.drvolte.spring_server.controller; + +import com.drvolte.spring_server.entity.PatientHistory; +import com.drvolte.spring_server.service.PatientHistoryService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/patienthistory") +public class PatientHistoryController { + + + private final PatientHistoryService patientHistoryService; + + + public PatientHistoryController(PatientHistoryService patientHistoryService) { + this.patientHistoryService = patientHistoryService; + } + + @PostMapping("/") + public ResponseEntity createPatientHistory(@RequestBody PatientHistory patient) { + return ResponseEntity.ok(patientHistoryService.createPatientHistory(patient)); + + } + + @GetMapping("/removeconsent/{id}") + public ResponseEntity updatePatientHistoryConsent(@PathVariable("id") Long id) { + return ResponseEntity.ok(patientHistoryService.updatePatientHistoryConsent(id)); + + } + + @GetMapping("/{id}") + public ResponseEntity getPatientHistoryById(@PathVariable("id") Long id) { + return ResponseEntity.ok(patientHistoryService.getPatientHistoryById(id)); + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientsController.java b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientsController.java new file mode 100644 index 0000000..5660e75 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/controller/PatientsController.java @@ -0,0 +1,47 @@ +package com.drvolte.spring_server.controller; + +import com.drvolte.spring_server.config.UserAuthenticationProvider; +import com.drvolte.spring_server.dtos.PatientRequestDto; +import com.drvolte.spring_server.dtos.PatientResponseDto; +import com.drvolte.spring_server.entity.Patient; +import com.drvolte.spring_server.service.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +public class PatientsController { + + @Autowired + private PatientService patientservice; + + @Autowired + private UserAuthenticationProvider userAuthenticationProvider; + + @PostMapping("/patients_register") + public ResponseEntity registerPatient(@RequestBody PatientRequestDto patientRequest) { + PatientResponseDto patientResponse = patientservice.registerOrLogin(patientRequest); + patientResponse.setToken(userAuthenticationProvider.createTokenForPatient(patientResponse)); + return ResponseEntity.ok(patientResponse); + } + + @GetMapping("/get_families") + public ResponseEntity> getFamilies(@RequestParam(value = "patient_id") Long patientId) { + List patients = patientservice.getFamilies(patientId); + return ResponseEntity.ok(patients); + } + + @PostMapping("/new_patient/{id}") + public ResponseEntity newPatient(@RequestBody Patient patient, @PathVariable(value = "id") Long id) { + + return ResponseEntity.status(201).body(patientservice.createPatient(patient, id)); + } + + @PutMapping("/new_patient/{id}") + public ResponseEntity updatePatient(@RequestBody Patient patient, @PathVariable(value = "id") Long id) { + + return ResponseEntity.status(201).body(patientservice.updatePatient(patient, id)); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallBackRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallBackRepository.java new file mode 100644 index 0000000..1c3273c --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallBackRepository.java @@ -0,0 +1,20 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.CallBack; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface CallBackRepository extends JpaRepository { + @RestResource(path = "/byattributes") + List findByCounsellorIdOrPatientIdOrStatus( + @Param(value = "counsellorid") Long counsellorId, + @Param(value = "patientid") Long patientId, + @Param(value = "status") String status + ); + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallHistoryRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallHistoryRepository.java new file mode 100644 index 0000000..641ae67 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CallHistoryRepository.java @@ -0,0 +1,28 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.CallHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface CallHistoryRepository extends JpaRepository { + + @RestResource(path = "/byids") + List findByPatientIdOrCounsellorIdOrderByCallStart( + @Param(value = "patientid") Long patientId, + + @Param(value = "counsellorid") Long counsellorId + ); + + + @RestResource(path = "/patientIdAndStatus") + List findByPatientIdAndStatus( + @Param(value = "patientid") Long patientId, + @Param(value = "status") String status + ); + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CounsellorRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CounsellorRepository.java new file mode 100644 index 0000000..467019e --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/CounsellorRepository.java @@ -0,0 +1,25 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.Counsellor; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface CounsellorRepository extends JpaRepository { + @RestResource(path = "byAttributes") + List findCounsellorsByEmailOrQualificationOrSpecialization( + @Param(value = "email") String email, + @Param(value = "specialization") String specialization, + @Param(value = "Qualification") String qualification + ); + + @RestResource(path = "byAttributesLike") + List findCounsellorsByQualificationContainingIgnoreCaseOrSpecializationContainingIgnoreCase( + @Param(value = "qualification") String qualification, + @Param(value = "specialization") String specialization + ); +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/DoctorRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/DoctorRepository.java new file mode 100644 index 0000000..1f03773 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/DoctorRepository.java @@ -0,0 +1,29 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.Doctor; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface DoctorRepository extends JpaRepository { + + @RestResource(path = "byAttributes") + List findDoctorsByEmailOrQualificationOrSpecialization( + @Param(value = "email") String email, + @Param(value = "specialization") String specialization, + @Param(value = "Qualification") String qualification + ); + + @RestResource(path = "byAttributesLike") + List findDoctorsByQualificationIsLikeIgnoreCaseOrSpecializationIsLikeIgnoreCase( + @Param(value = "qualification") String qualification, + @Param(value = "specialization") String specialization + ); + + Optional findByEmail(String firstName); +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientHistoryRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientHistoryRepository.java new file mode 100644 index 0000000..40afb15 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientHistoryRepository.java @@ -0,0 +1,19 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.PatientHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@Repository +public interface PatientHistoryRepository extends JpaRepository { + @RestResource(path = "/byattributes") + List findByPatientIdAndConsent( + @Param(value = "patientid") Long patientId, + @RequestParam(value = "consent", defaultValue = "true") Boolean consent + ); +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientRepository.java new file mode 100644 index 0000000..d9dd798 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/PatientRepository.java @@ -0,0 +1,17 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.Patient; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + + +@Repository +public interface PatientRepository extends JpaRepository { + Optional findPatientByPhNumber(String phNumber); + + List findAllByPhNumber(String phNumber); + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/SeniorDrRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/SeniorDrRepository.java new file mode 100644 index 0000000..8bd804e --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/SeniorDrRepository.java @@ -0,0 +1,27 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.SeniorDr; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface SeniorDrRepository extends JpaRepository { + + @RestResource(path = "byAttributes") + List findSeniorDrsByEmailOrQualificationOrSpecialization( + @Param(value = "email") String email, + @Param(value = "specialization") String specialization, + @Param(value = "Qualification") String qualification + ); + + @RestResource(path = "byAttributesLike") + List findSeniorDrsByQualificationIsLikeIgnoreCaseOrSpecializationIsLikeIgnoreCase( + @Param(value = "qualification") String qualification, + @Param(value = "specialization") String specialization + ); + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dao/UserRepository.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/UserRepository.java new file mode 100644 index 0000000..3b7c020 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dao/UserRepository.java @@ -0,0 +1,13 @@ +package com.drvolte.spring_server.dao; + +import com.drvolte.spring_server.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + @RestResource(path = "byAttribute") + Optional findByUsername( @Param(value = "username")String username); +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/CredentialsDto.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/CredentialsDto.java new file mode 100644 index 0000000..31f6191 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/CredentialsDto.java @@ -0,0 +1,5 @@ +package com.drvolte.spring_server.dtos; + +public record CredentialsDto(String username, String password) { + +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/ErrorDto.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/ErrorDto.java new file mode 100644 index 0000000..715ea6c --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/ErrorDto.java @@ -0,0 +1,4 @@ +package com.drvolte.spring_server.dtos; + +public record ErrorDto(String message) { +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/FileUploadResponseDTO.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/FileUploadResponseDTO.java new file mode 100644 index 0000000..b6b67d9 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/FileUploadResponseDTO.java @@ -0,0 +1,11 @@ +package com.drvolte.spring_server.dtos; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class FileUploadResponseDTO { + private String fileUploadStatus; + private String filePath; +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientRequestDto.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientRequestDto.java new file mode 100644 index 0000000..3210db9 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientRequestDto.java @@ -0,0 +1,5 @@ +package com.drvolte.spring_server.dtos; + +public record PatientRequestDto (String phnumber, String state){ + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientResponseDto.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientResponseDto.java new file mode 100644 index 0000000..7c76873 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/PatientResponseDto.java @@ -0,0 +1,18 @@ +package com.drvolte.spring_server.dtos; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PatientResponseDto { + private String phnumber; + private Long id; + private String state; + private String token; + private String role; +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/UserDto.java b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/UserDto.java new file mode 100644 index 0000000..42e220c --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/dtos/UserDto.java @@ -0,0 +1,19 @@ +package com.drvolte.spring_server.dtos; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UserDto { + private long id; + private String firstName; + private String lastName; + private String username; + private String token; + private String role; +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallBack.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallBack.java new file mode 100644 index 0000000..8e2ef88 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallBack.java @@ -0,0 +1,38 @@ +package com.drvolte.spring_server.entity; + +import jakarta.persistence.*; +import lombok.Data; + +import java.util.Date; + +@Data +@Entity +@Table(name = "callback") +public class CallBack { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "counsellor_id", nullable = false) + private Counsellor counsellor; + + @ManyToOne + @JoinColumn(name = "patient_id", nullable = false) + private Counsellor patient; + + @Column(name = "followup_reason", nullable = true) + private String followupReason; + + @Column(name = "schedule", nullable = false) + private Date schedule; + + @Column(name = "status", nullable = false) + private String status; + + public Long getResourceId(){ + return id; + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallHistory.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallHistory.java new file mode 100644 index 0000000..1a3244f --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/CallHistory.java @@ -0,0 +1,38 @@ +package com.drvolte.spring_server.entity; + + +import jakarta.persistence.*; +import lombok.Data; + +import java.util.Date; + +@Data +@Entity +@Table(name = "call_history") +public class CallHistory { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "counsellor_id", referencedColumnName = "doctor_id", nullable = false) + private Counsellor counsellor; + + @ManyToOne + @JoinColumn(name = "patient_id", referencedColumnName = "id", nullable = false) + private Patient patient; + + @Column(name = "call_start", nullable = false) + private Date callStart; + + @Column(name = "call_end", nullable = false) + private Date callEnd; + + @Column(name = "status", nullable = false) + private String status; + + public Long getResourceId(){ + return id; + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Counsellor.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Counsellor.java new file mode 100644 index 0000000..a744a0f --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Counsellor.java @@ -0,0 +1,17 @@ +package com.drvolte.spring_server.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Entity +@Table(name = "counsellor") +@PrimaryKeyJoinColumn(name = "doctor_id") +@Data +@EqualsAndHashCode(callSuper = true) +public class Counsellor extends Doctor { + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Doctor.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Doctor.java new file mode 100644 index 0000000..2be5b0d --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Doctor.java @@ -0,0 +1,52 @@ +package com.drvolte.spring_server.entity; + +import jakarta.persistence.*; +import lombok.Data; + +import java.util.Date; + +@Entity +@Table(name = "doctor") +@Inheritance(strategy = InheritanceType.JOINED) +@Data +public class Doctor { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "email", nullable = false, unique = true) + private String email; + + @Column(name = "specialization", nullable = false) + private String specialization; + + @Column(name = "hospital_name", nullable = true) + private String hospital_name; + + @Column(name = "hospital_address", nullable = true) + private String hospital_address; + + @Column(name = "qualification", nullable = false) + private String qualification; + + @Column(name = "profile_photo", nullable = true) + private String profile_photo; + + @Column(name = "dob", nullable = false) + private Date date; + + @Column(name = "status", nullable = false) + private String status; + + @Column(name = "languagues", nullable = true) + private String languages; + + public Long getResourceId(){ + return id; + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Notification.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Notification.java new file mode 100644 index 0000000..3897d67 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Notification.java @@ -0,0 +1,26 @@ +package com.drvolte.spring_server.entity; + +import com.drvolte.spring_server.models.Roles; +import jakarta.persistence.*; + +@Entity +@Table(name = "notifications") +public class Notification { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "user_id", nullable = false) + private Long userId; + + @Column(name = "role", nullable = false) + private Roles role; + + @Column(name = "message", nullable = false) + private String message; + + public Long getResourceId(){ + return id; + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Patient.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Patient.java new file mode 100644 index 0000000..7e1cc95 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/Patient.java @@ -0,0 +1,54 @@ +package com.drvolte.spring_server.entity; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Data +@Table(name = "patient") +public class Patient { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "ph_no", nullable = false) + private String phNumber; + + @Column(name = "name", nullable = true) + private String name; + + @Column(name = "location", nullable = true) + private String location; + + @Column(name = "major_issues", nullable = true) + private String major_issues; + + @Column(name = "minor_issues", nullable = true) + private String minor_issues; + + @Column(name = "allergies", nullable = true) + private String allergies; + + @Column(name = "blood_group", nullable = true) + private String blood_group; + + @Column(name = "state", nullable = false) + private String state; + + @Column(name = "languague", nullable = true) + private String languague; + + @Column(name = "test_suggested") + private String test_suggested; + + @Column(name = "gender") + private String gender; + + @Column(name = "dob", nullable = true) + private String dob; + + public Long getResourceId() { + return id; + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/PatientHistory.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/PatientHistory.java new file mode 100644 index 0000000..3a31903 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/PatientHistory.java @@ -0,0 +1,45 @@ +package com.drvolte.spring_server.entity; + + +import jakarta.persistence.*; +import lombok.Data; + +import java.util.Date; + +@Data +@Entity +@Table(name = "patient_history") +public class PatientHistory { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "patient_id", nullable = false) + private Patient patient; + + @Column(name = "symptoms", nullable = false) + private String symptoms; + + @Column(name = "summanry", nullable = false) + private String summanry; + + @Column(name = "prescription", nullable = false) + private String prescription; + + @Column(name = "consent", nullable = false) + private Boolean consent; + + @Column(name = "audio_recording", nullable = false) + private String audio_recording; + + @Column(name = "created", nullable = false) + private Date created; + + public Long getResourceId() { + return id; + } + + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/SeniorDr.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/SeniorDr.java new file mode 100644 index 0000000..e79805f --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/SeniorDr.java @@ -0,0 +1,17 @@ +package com.drvolte.spring_server.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Entity +@Table(name = "senior_dr") +@PrimaryKeyJoinColumn(name = "doctor_id") +@Data +@EqualsAndHashCode(callSuper = true) +public class SeniorDr extends Doctor { + + +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/entity/User.java b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/User.java new file mode 100644 index 0000000..2b20890 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/entity/User.java @@ -0,0 +1,40 @@ +package com.drvolte.spring_server.entity; + +import com.drvolte.spring_server.models.Roles; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +@Table(name = "users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "username", nullable = false) + private String username; + + @Column(name = "password", nullable = false) + private String password; + + @Column(name = "role", nullable = false) + private Roles role; + + @Column(name = "enable", nullable = false) + private boolean enable; + + public Long getResourceId(){ + return id; + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/exceptions/AppException.java b/Spring_Server/src/main/java/com/drvolte/spring_server/exceptions/AppException.java new file mode 100644 index 0000000..c2864c2 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/exceptions/AppException.java @@ -0,0 +1,16 @@ +package com.drvolte.spring_server.exceptions; + +import org.springframework.http.HttpStatus; + +public class AppException extends RuntimeException { + private final HttpStatus httpStatus; + + public AppException(String message, HttpStatus httpStatus) { + super(message); + this.httpStatus = httpStatus; + } + + public HttpStatus getHttpStatus() { + return httpStatus; + } +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/PatientMapper.java b/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/PatientMapper.java new file mode 100644 index 0000000..d15336e --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/PatientMapper.java @@ -0,0 +1,28 @@ +package com.drvolte.spring_server.mappers; + +import com.drvolte.spring_server.dtos.PatientRequestDto; +import com.drvolte.spring_server.dtos.PatientResponseDto; +import com.drvolte.spring_server.entity.Patient; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface PatientMapper { + @Mapping(source = "phNumber", target = "phnumber") + public PatientResponseDto patientToPatientResponseDto(Patient patient); + + + @Mapping(source = "phnumber", target = "phNumber") + @Mapping(source = "state", target = "state") + public Patient patientRequestDtoToPatient(PatientRequestDto patientRequestDto); + + + @Mapping(source = "phnumber", target = "phNumber") + @Mapping(source = "state", target = "state") + @Mapping(source = "id", target = "id") + public Patient patientResponseDtoToPatient(PatientResponseDto patientResponseDto); + + + + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/UserMapper.java b/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/UserMapper.java new file mode 100644 index 0000000..731d946 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/mappers/UserMapper.java @@ -0,0 +1,13 @@ +package com.drvolte.spring_server.mappers; + +import com.drvolte.spring_server.dtos.UserDto; +import com.drvolte.spring_server.entity.User; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface UserMapper { + @Mapping(source = "role", target = "role") + @Mapping(source = "name", target = "firstName") + UserDto touserDto(User user); +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/models/ChangePasswordStructure.java b/Spring_Server/src/main/java/com/drvolte/spring_server/models/ChangePasswordStructure.java new file mode 100644 index 0000000..0740bd8 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/models/ChangePasswordStructure.java @@ -0,0 +1,11 @@ +package com.drvolte.spring_server.models; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ChangePasswordStructure { + private String password; + private String token; +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/models/EmailStructure.java b/Spring_Server/src/main/java/com/drvolte/spring_server/models/EmailStructure.java new file mode 100644 index 0000000..8447bf0 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/models/EmailStructure.java @@ -0,0 +1,13 @@ +package com.drvolte.spring_server.models; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class EmailStructure { + + private String subject; + private String message; + +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/models/Roles.java b/Spring_Server/src/main/java/com/drvolte/spring_server/models/Roles.java new file mode 100644 index 0000000..91fd711 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/models/Roles.java @@ -0,0 +1,12 @@ +package com.drvolte.spring_server.models; + +public enum Roles { + COUNSELLOR, + PATIENT, + SENIORDR, + ADMIN, + ROLE_COUNSELLOR, + ROLE_PATIENT, + ROLE_SENIORDR, + ROLE_ADMIN +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketConnection.java b/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketConnection.java new file mode 100644 index 0000000..d7b9d2c --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketConnection.java @@ -0,0 +1,38 @@ +package com.drvolte.spring_server.models; + +import lombok.Data; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Data +public class WebSocketConnection { + + // Token to session id mapping + private Map tokenToSessionId; + // Session Id to token mapping + private Map sessionIdToToken; + // Roles to state and then each state to token + private Map>> roleToStateToToken; + // Token to token forwarding mapping based on role as there can be only 3 roles involed in a call + private Map> tokenToRoleToToken; + // its role to their id (id in entity) + private Map> roleToIdToToken; + // queue for patients in call + private Queue waitQueue; + // missied call (means they callled and didnt want to wait and cut the call as counsellors are busy) + private Queue missedCalls; + + public WebSocketConnection() { + this.tokenToSessionId = new HashMap(); + this.sessionIdToToken = new HashMap(); + this.roleToStateToToken = new HashMap>>(); + this.tokenToRoleToToken = new HashMap>(); + this.roleToIdToToken = new HashMap>(); + this.waitQueue = new LinkedList<>(); + this.missedCalls = new LinkedList<>(); + + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketMessage.java b/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketMessage.java new file mode 100644 index 0000000..c26dc98 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/models/WebSocketMessage.java @@ -0,0 +1,74 @@ +package com.drvolte.spring_server.models; + +import lombok.Data; +import org.json.JSONObject; +import org.springframework.web.socket.TextMessage; + +@Data +public class WebSocketMessage { + private String data; + private String event; + private String token; + private String source; + private String destination; + + public WebSocketMessage(String data, String event, String token, String source, String destination) { + this.data = data; + this.event = event; + this.token = token; + this.source = source; + this.destination = destination; + } + + public WebSocketMessage() { + this.data = ""; + this.event = ""; + this.token = ""; + this.source = ""; + this.destination = ""; + } + + public WebSocketMessage(TextMessage message) { + JSONObject messageJSON = new JSONObject(message.getPayload()); + System.out.println("Createinga socketmessage: " + messageJSON); + this.token = messageJSON.getString("token"); + this.data = messageJSON.getString("data"); + this.event = messageJSON.getString("event"); + this.source = messageJSON.getString("source"); + this.destination = messageJSON.getString("destination"); + } + + public WebSocketMessage setItems(String data, String event, String token, String source, String destination) { + this.data = data; + this.event = event; + this.token = token; + this.source = source; + this.destination = destination; + return this; + } + + public WebSocketMessage setItems(TextMessage message) { + + JSONObject messageJSON = new JSONObject(message.getPayload()); + System.out.println("Createinga socketmessage: " + messageJSON); + this.token = messageJSON.getString("token"); + this.data = messageJSON.getString("data"); + this.event = messageJSON.getString("event"); + this.source = messageJSON.getString("source"); + this.destination = messageJSON.getString("destination"); + return this; + + } + + @Override + public String toString() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("data", this.data); + jsonObject.put("event", this.event); + jsonObject.put("token", this.token); + jsonObject.put("source", this.source); + jsonObject.put("destination", this.destination); + return jsonObject.toString(); + } + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/EmailService.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/EmailService.java new file mode 100644 index 0000000..b034069 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/EmailService.java @@ -0,0 +1,29 @@ +package com.drvolte.spring_server.service; + +import com.drvolte.spring_server.models.EmailStructure; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; + +@Service +public class EmailService { + + @Autowired + private JavaMailSender emailSender; + + @Value("$(spring.mail.username)") + private String fromEmailId; + + public void sendMail(String emailId, EmailStructure emailStructure) + { + SimpleMailMessage mailMessage = new SimpleMailMessage(); + mailMessage.setFrom(fromEmailId); + mailMessage.setSubject(emailStructure.getSubject()); + mailMessage.setText(emailStructure.getMessage()); + mailMessage.setTo(emailId); + + emailSender.send(mailMessage); + } +} diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/FileStorageService.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/FileStorageService.java new file mode 100644 index 0000000..0c305ba --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/FileStorageService.java @@ -0,0 +1,79 @@ +package com.drvolte.spring_server.service; + +import com.drvolte.spring_server.dtos.FileUploadResponseDTO; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MaxUploadSizeExceededException; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +@Service +public class FileStorageService { + + private final String relativeFolderPath = "assets" + File.separator; + + @Value("${spring.servlet.multipart.max-file-size}") + private String maxFileSize; + + public ResponseEntity uploadImage(MultipartFile file) throws IOException { + + FileUploadResponseDTO fileUploadResponseDTO = null; + + if (file.getSize() > parseSize(maxFileSize)) + throw new MaxUploadSizeExceededException(parseSize(maxFileSize)); + + // Get the application's current working directory + String currentDirectory = System.getProperty("user.dir"); + // Construct the absolute path by appending the relative path + String folderPath = currentDirectory + File.separator + relativeFolderPath; + + System.out.println("Relative folder path : " + relativeFolderPath); + + File folder = new File(folderPath); + if (!folder.exists()) { + // Folder does not exist. Hence, create the folder. + boolean folderCreated = folder.mkdirs(); + if (folderCreated) { + System.out.println("Folder created successfully."); + } else { + System.out.println("Failed to create folder."); + } + } else { + // Folder exists, so don't create it. + System.out.println("Folder already exists."); + } + + String fileName = file.getOriginalFilename(); + String filePath = folderPath + fileName; + file.transferTo(new File(filePath)); + fileUploadResponseDTO = FileUploadResponseDTO.builder() + .fileUploadStatus("Success") + .filePath(File.separator + relativeFolderPath + fileName) + .build(); + return ResponseEntity.ok(fileUploadResponseDTO); + } + + public byte[] downloadImage(String filePath) throws IOException { + + String currentDirectory = System.getProperty("user.dir"); + String absoluteFilePath = currentDirectory + "\\" + filePath; + return Files.readAllBytes(new File(absoluteFilePath).toPath()); + } + + + private long parseSize(String size) { + size = size.toUpperCase(); + long parsedLong = Long.parseLong(size.substring(0, size.length() - 2)); + if (size.endsWith("KB")) { + return parsedLong * 1024; + } else if (size.endsWith("MB")) { + return parsedLong * 1024 * 1024; + } else { + return Long.parseLong(size); + } + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientHistoryService.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientHistoryService.java new file mode 100644 index 0000000..25332b3 --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientHistoryService.java @@ -0,0 +1,39 @@ +package com.drvolte.spring_server.service; + +import com.drvolte.spring_server.dao.PatientHistoryRepository; +import com.drvolte.spring_server.entity.PatientHistory; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class PatientHistoryService { + + private final PatientHistoryRepository patientHistoryRepository; + + public PatientHistoryService(PatientHistoryRepository patientHistoryRepository) { + this.patientHistoryRepository = patientHistoryRepository; + } + + public PatientHistory createPatientHistory(PatientHistory patient) { + return patientHistoryRepository.save(patient); + } + + public Boolean updatePatientHistoryConsent(Long id) { + Optional optionalPatientHistory = patientHistoryRepository.findById(id); + if (optionalPatientHistory.isPresent()) { + PatientHistory patientHistory = optionalPatientHistory.get(); + patientHistory.setConsent(false); + patientHistoryRepository.save(patientHistory); + return true; + } else { + return false; + } + } + + + public PatientHistory getPatientHistoryById(Long id) { + Optional optionalPatientHistory = patientHistoryRepository.findById(id); + return optionalPatientHistory.orElse(null); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientService.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientService.java new file mode 100644 index 0000000..37465cb --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/PatientService.java @@ -0,0 +1,81 @@ +package com.drvolte.spring_server.service; + +import com.drvolte.spring_server.dao.PatientRepository; +import com.drvolte.spring_server.dtos.PatientRequestDto; +import com.drvolte.spring_server.dtos.PatientResponseDto; +import com.drvolte.spring_server.entity.Patient; +import com.drvolte.spring_server.mappers.PatientMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class PatientService { + + @Autowired + private PatientRepository patientRepository; + + @Autowired // Add this annotation for autowiring + private PatientMapper patientMapper; + + public PatientResponseDto registerOrLogin(PatientRequestDto patientRequest) { + System.out.println("Patients Phnumber: " + patientRequest.phnumber()); + + List existingPatientOptional = patientRepository.findAllByPhNumber(patientRequest.phnumber()); + System.out.println("this is the response for DataBase for searching by Phnumber" + existingPatientOptional); + if (!existingPatientOptional.isEmpty()) { + Patient existingPatient = existingPatientOptional.get(0); + System.out.println("Present" + existingPatient); + PatientResponseDto temp = patientMapper.patientToPatientResponseDto(existingPatient); + temp.setRole("ROLE_PATIENT"); + return temp; + } else { + // Create a new patient + System.out.println("Not Present"); + Patient newPatient = patientMapper.patientRequestDtoToPatient(patientRequest); + Patient savedPatient = patientRepository.save(newPatient); + PatientResponseDto temp = patientMapper.patientToPatientResponseDto(savedPatient); + temp.setRole("ROLE_PATIENT"); + return temp; + } + } + + public List getFamilies(Long patientId) { + Optional patientsOptional = patientRepository.findById(patientId); + if (patientsOptional.isPresent()) { + String phNumber = patientsOptional.get().getPhNumber(); + return patientRepository.findAllByPhNumber(phNumber); + } else { + return new ArrayList(); + } + + } + + public Patient createPatient(Patient patient, Long id) { + List patients = this.getFamilies(id); + if (!patients.isEmpty()) { + String phNumber = patients.get(0).getPhNumber(); + patient.setPhNumber(phNumber); + } + return patientRepository.save((patient)); + + } + + public Patient updatePatient(Patient patient, Long id) { + Optional patients = patientRepository.findById(id); + if (patients.isPresent()) { + Patient fectchedPatient = patients.get(); + String phNumber = fectchedPatient.getPhNumber(); + patient.setPhNumber(phNumber); + patient.setId(id); + } else { + System.out.println("this patient is not present: " + id + " " + patient); + } + return patientRepository.save((patient)); + } + + +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/UserService.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/UserService.java new file mode 100644 index 0000000..e85ebda --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/UserService.java @@ -0,0 +1,31 @@ +package com.drvolte.spring_server.service; + +import com.drvolte.spring_server.dao.UserRepository; +import com.drvolte.spring_server.dtos.CredentialsDto; +import com.drvolte.spring_server.dtos.UserDto; +import com.drvolte.spring_server.entity.User; +import com.drvolte.spring_server.exceptions.AppException; +import com.drvolte.spring_server.mappers.UserMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserService { + private final UserRepository userRepository; + private final PasswordEncoder passowrdEncoderConfig; + private final UserMapper userMapper; + + public UserDto login(CredentialsDto credentialsDto) { + System.out.println("This is the username logging"); + User user = userRepository.findByUsername(credentialsDto.username()) + .orElseThrow(() -> new AppException("Username Not Found", HttpStatus.NOT_FOUND)); + System.out.println("inside the userservices" + user); + if (passowrdEncoderConfig.matches(credentialsDto.password(), user.getPassword())) { + return userMapper.touserDto(user); + } + throw new AppException("Invalid Password", HttpStatus.BAD_REQUEST); + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/java/com/drvolte/spring_server/service/WebSocketHandler.java b/Spring_Server/src/main/java/com/drvolte/spring_server/service/WebSocketHandler.java new file mode 100644 index 0000000..52c632d --- /dev/null +++ b/Spring_Server/src/main/java/com/drvolte/spring_server/service/WebSocketHandler.java @@ -0,0 +1,578 @@ +package com.drvolte.spring_server.service; + +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.drvolte.spring_server.config.UserAuthenticationProvider; +import com.drvolte.spring_server.models.Roles; +import com.drvolte.spring_server.models.WebSocketConnection; +import com.drvolte.spring_server.models.WebSocketMessage; +import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +import java.io.IOException; +import java.util.*; + +@Component +public class WebSocketHandler extends TextWebSocketHandler { + private static final Logger logger = LoggerFactory.getLogger(WebSocketHandler.class); + private static final String SET_TOKEN_EVENT = "settoken", + CONNECT_EVENT = "connect", + DECLINE_EVENT = "decline", + STATECHANGE_EVENT = "changestate", + ADDTOQUEUE_EVENT = "addtoqueue", + ADDTOMISSED_EVENT = "addtomissed", + REMOVEQUEUE_EVENT = "removequeue", + REMOVEMISSED_EVENT = "removemissed", + CONNECT_PATIENT = "connectpatient", + CONNECT_COUNSELLOR = "connectcounsellor", + CONNECT_QUEUE = "connectqueue", + CONNECT_MISSED = "connectmissed", + STATE_CONNECTED = "connected", + STATE_INCALL = "incall", + STATE_BUSY = "busy"; + private final Map sessions = Collections.synchronizedMap(new HashMap<>()); + private final WebSocketConnection webSocketConnections; + private final UserAuthenticationProvider jwtAuthProvider; + private final WebSocketMessage tempWebsocketMessage; + + public WebSocketHandler(WebSocketConnection webSocketConnections, UserAuthenticationProvider jwtAuthProvider) { + logger.info("Creating a new SocketHandler"); + this.webSocketConnections = webSocketConnections; + this.jwtAuthProvider = jwtAuthProvider; + this.tempWebsocketMessage = new WebSocketMessage(); + } + + @Override + public void handleTextMessage(@Nullable WebSocketSession sourceSession, @Nullable TextMessage message) + throws IOException { + WebSocketMessage socketMessage = new WebSocketMessage(); + try { + if (message == null) { + logger.warn("Received a null message"); + return; + } + + logger.info("Got the message: {}", message.getPayload()); + socketMessage.setItems(message); + logger.info("socketmessage {}", socketMessage); + + switch (socketMessage.getEvent()) { + case SET_TOKEN_EVENT -> { + logger.info("its an setToken event"); + assert sourceSession != null; + handleSetTokenEvent(sourceSession, socketMessage); + break; + } + case CONNECT_EVENT -> { + logger.info("its an connect event"); + assert sourceSession != null; + handleConnectEvent(sourceSession, socketMessage); + } + case DECLINE_EVENT -> { + logger.info("its an decline event"); + assert sourceSession != null; + try { + forwardMessage(sourceSession, socketMessage); + } catch (NullPointerException e) { + handleDeclineEvent(sourceSession, socketMessage); + throw e; + } + handleDeclineEvent(sourceSession, socketMessage); + } + case CONNECT_PATIENT -> { + logger.info("Senior Dr connecting Patient"); + handleConnectPatientEvent(sourceSession, socketMessage); + } + case CONNECT_COUNSELLOR -> { + logger.info("Senior Dr connecting counsellot"); + handleConnectCounsellorEvent(sourceSession, socketMessage); + } + case STATECHANGE_EVENT -> { + logger.info("Sett event occured"); + assert sourceSession != null; + handleChangeStateEvent(sourceSession, socketMessage); + } + case ADDTOQUEUE_EVENT -> { + logger.info("Add to Queue event occured"); + assert sourceSession != null; + handleAddToQueueEvent(sourceSession, socketMessage); + } + case ADDTOMISSED_EVENT -> { + logger.info("Add to missed event occured"); + assert sourceSession != null; + handleAddToMissedEvent(sourceSession, socketMessage); + } + case REMOVEQUEUE_EVENT -> { + logger.info("remove from queue event occured"); + assert sourceSession != null; + handleRemoveQueueEvent(sourceSession, socketMessage); + } + case REMOVEMISSED_EVENT -> { + logger.info("remove from missed event occured"); + assert sourceSession != null; + handleRemoveMissedEvent(sourceSession, socketMessage); + } + case CONNECT_QUEUE -> { + logger.info("Connect from queue event occured"); + assert sourceSession != null; + handleConnectQueueEvent(sourceSession, socketMessage); + } + case CONNECT_MISSED -> { + logger.info("Connect from missed event occured"); + assert sourceSession != null; + handleConnectMissedEvent(sourceSession, socketMessage); + } + case null, default -> { + logger.info("forwarding"); + assert sourceSession != null; + forwardMessage(sourceSession, socketMessage); + } + } + } catch (JWTVerificationException e) { + logger.error("JWTVerificationException occuered"); + assert sourceSession != null; + sendTextMessage(sourceSession, tempWebsocketMessage.setItems("HandleTextmsg: Invalid JWT token", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } catch (Exception e) { + logger.error("Error handling WebSocket message", e); + } + } + + private void handleConnectMissedEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + Long patientId = webSocketConnections.getMissedCalls().poll(); + String sourceToken = socketMessage.getToken(); + + + assert patientId != null; + WebSocketMessage newSocketMsg = new WebSocketMessage( + patientId.toString(), + "connect", + sourceToken, + socketMessage.getSource(), + socketMessage.getDestination() + ); + handleConnectEvent(sourceSession, newSocketMsg); + } + + private void handleConnectQueueEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + Long patientId = webSocketConnections.getWaitQueue().poll(); + String sourceToken = socketMessage.getToken(); + + + assert patientId != null; + WebSocketMessage newSocketMsg = new WebSocketMessage( + patientId.toString(), + "connect", + sourceToken, + socketMessage.getSource(), + socketMessage.getDestination() + ); + handleConnectEvent(sourceSession, newSocketMsg); + } + + private void handleRemoveQueueEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) { + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + Long source_Id = getIdFromToken(sourceToken); + webSocketConnections.getWaitQueue().remove(source_Id); + + } + + private void handleRemoveMissedEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) { + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + Long source_Id = getIdFromToken(sourceToken); + webSocketConnections.getMissedCalls().remove(source_Id); + + } + + private void handleAddToMissedEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) { + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + Long source_Id = getIdFromToken(sourceToken); + if (!webSocketConnections.getMissedCalls().contains(source_Id)) + webSocketConnections.getMissedCalls().add(source_Id); + } + + private void handleAddToQueueEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) { + + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + Long source_Id = getIdFromToken(sourceToken); + if (!webSocketConnections.getWaitQueue().contains(source_Id)) + webSocketConnections.getWaitQueue().add(source_Id); + } + + private void handleChangeStateEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + String token = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + String presentState = socketMessage.getData().split(":")[0]; + String toState = socketMessage.getData().split(":")[1]; + System.out.println("CHanging state from " + presentState + " to " + toState); + updateTheSate(token, presentState, toState); + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("changeStateSuccessfully", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + + private void handleConnectCounsellorEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + String destToken = webSocketConnections.getRoleToIdToToken() + .get(Roles.valueOf(socketMessage.getDestination())) + .get(Long.parseLong(socketMessage.getData())); + if (destToken != null) { + addTokenToTokenSet( + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + destToken, + getRoleFromToken(destToken)); + addTokenToTokenSet( + destToken, + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + getRoleFromToken(webSocketConnections.getSessionIdToToken().get(sourceSession.getId())) + ); + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("counsellorConnected", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + sendTextMessage(sessions.get( + webSocketConnections.getTokenToSessionId().get(destToken)), + tempWebsocketMessage.setItems("srDrConnect", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } else { + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("counsellorNotAvailable", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + } + + private void handleConnectPatientEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + String destToken = webSocketConnections.getRoleToIdToToken() + .get(Roles.valueOf(socketMessage.getDestination())) + .get(Long.parseLong(socketMessage.getData())); + System.out.println("inside connect patient event: " + destToken); + if (destToken != null) { + addTokenToTokenSet( + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + destToken, + getRoleFromToken(destToken)); + System.out.println("adtokentotokenSet Done1"); + addTokenToTokenSet( + destToken, + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + getRoleFromToken(webSocketConnections.getSessionIdToToken().get(sourceSession.getId())) + ); + + System.out.println("adtokentotokenSet Done2"); + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("patientConnected", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + sendTextMessage(sessions.get( + webSocketConnections.getTokenToSessionId().get(destToken)), + tempWebsocketMessage.setItems("seniorDoctorConnecting", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } else { + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("patientNotAvailable", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + } + + private void handleDeclineEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) { + String token = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + updateTheSate(token, STATE_INCALL, STATE_CONNECTED); + System.out.println("this is the Token to ROle to Token " + webSocketConnections.getTokenToRoleToToken()); + System.out.println("removing the " + Roles.valueOf(socketMessage.getDestination()) + " from this token: " + token); + + if (socketMessage.getData().equals("disconnect")) { + String counsellorToken, srDrToken, patientToken; + counsellorToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_COUNSELLOR, null); + srDrToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_SENIORDR, null); + patientToken = webSocketConnections.getTokenToRoleToToken().get(token).getOrDefault(Roles.ROLE_PATIENT, null); + webSocketConnections.getTokenToRoleToToken().remove(token); + System.out.println("Disconnect call:" + patientToken + " \n" + counsellorToken + "\n" + srDrToken); + if (patientToken != null) + webSocketConnections.getTokenToRoleToToken().remove(patientToken); + if (counsellorToken != null) + webSocketConnections.getTokenToRoleToToken().remove(counsellorToken); + if (srDrToken != null) + webSocketConnections.getTokenToRoleToToken().remove(srDrToken); + } else { + webSocketConnections.getTokenToRoleToToken() + .getOrDefault(token, new HashMap<>()) + .remove( + Roles.valueOf(socketMessage.getDestination()) + ); + } + + logger.info("User connection declined" + token); + } + + private void handleSetTokenEvent(WebSocketSession session, WebSocketMessage socketMessage) throws IOException { + System.out.println(webSocketConnections); + /* + * - when any client sends the set token request + * - set the session to token and vice versa + * - set the role to state to token for every one + */ + + DecodedJWT tempdecodedJWT; + String sourceToken = socketMessage.getToken(); + DecodedJWT sourceDecodedJWT = jwtAuthProvider.getDecoded(sourceToken); + Long sourceId = sourceDecodedJWT.getClaim("id").asLong(); + Roles sourceRole = Roles.valueOf(socketMessage.getSource()); + Iterator tempTokenIterator = webSocketConnections.getTokenToRoleToToken().keySet().iterator(); + while (tempTokenIterator.hasNext()) { + String tempToken = tempTokenIterator.next(); + try { + tempdecodedJWT = jwtAuthProvider.getDecoded(tempToken); + Long tempId = tempdecodedJWT.getClaim("id").asLong(); + Roles tempRole = Roles.valueOf(tempdecodedJWT.getClaim("role").asString()); + if (sourceId.equals(tempId) && sourceRole.equals(tempRole)) { + try { + Roles role = Roles.valueOf(tempdecodedJWT.getClaim("role").asString()); + Long id = tempdecodedJWT.getClaim("id").asLong(); + System.out.println(("this is the role and id for the token " + role + " " + id)); + Iterator stateIterator = webSocketConnections.getRoleToStateToToken().get(role).keySet().iterator(); + while (stateIterator.hasNext()) { + String state = stateIterator.next(); + webSocketConnections.getRoleToStateToToken().get(role).get(state).remove(tempToken); + } + + String counsellorToken, srDrToken, patientToken; + if (webSocketConnections.getTokenToRoleToToken().containsKey(tempToken)) { + counsellorToken = webSocketConnections.getTokenToRoleToToken().get(tempToken).getOrDefault(Roles.ROLE_COUNSELLOR, null); + srDrToken = webSocketConnections.getTokenToRoleToToken().get(tempToken).getOrDefault(Roles.ROLE_SENIORDR, null); + patientToken = webSocketConnections.getTokenToRoleToToken().get(tempToken).getOrDefault(Roles.ROLE_PATIENT, null); + tempTokenIterator.remove(); + System.out.println("removing the token from tokentoroletotoken for logout:" + patientToken + " \n" + counsellorToken + "\n" + srDrToken); + if (patientToken != null) + webSocketConnections.getTokenToRoleToToken().remove(patientToken); + if (counsellorToken != null) + webSocketConnections.getTokenToRoleToToken().remove(counsellorToken); + if (srDrToken != null) + webSocketConnections.getTokenToRoleToToken().remove(srDrToken); + } + webSocketConnections.getRoleToIdToToken().get(role).remove(id); + + } catch (JWTVerificationException ignored) { + System.out.println("Token validation erro"); + } + } + } catch (JWTVerificationException e) { + System.out.println("jwt invalid in getTokenroletoken " + tempToken); + tempTokenIterator.remove(); + } + + } + Iterator tempSessionIdIterator = webSocketConnections.getSessionIdToToken().keySet().iterator(); + while (tempSessionIdIterator.hasNext()) { + String tempSessionId = tempSessionIdIterator.next(); + String tempToken = webSocketConnections.getSessionIdToToken().get(tempSessionId); + try { + tempdecodedJWT = jwtAuthProvider.getDecoded(tempToken); + Long tempId = tempdecodedJWT.getClaim("id").asLong(); + Roles tempRole = Roles.valueOf(tempdecodedJWT.getClaim("role").asString()); + + if (sourceId.equals(tempId) && sourceRole.equals(tempRole)) + tempSessionIdIterator.remove(); + } catch (JWTVerificationException e) { + tempSessionIdIterator.remove(); + } + + } + this.webSocketConnections.getSessionIdToToken().put(session.getId(), sourceToken); + + + tempTokenIterator = webSocketConnections.getTokenToSessionId().keySet().iterator(); + while (tempTokenIterator.hasNext()) { + String tempToken = tempTokenIterator.next(); + try { + tempdecodedJWT = jwtAuthProvider.getDecoded(tempToken); + Long tempId = tempdecodedJWT.getClaim("id").asLong(); + Roles tempRole = Roles.valueOf(tempdecodedJWT.getClaim("role").asString()); + if (sourceId.equals(tempId) && sourceRole.equals(tempRole)) + tempTokenIterator.remove(); + } catch (JWTVerificationException e) { + tempTokenIterator.remove(); + } + + } + this.webSocketConnections.getTokenToSessionId().put(sourceToken, session.getId()); + + + try { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(sourceToken); + Roles role = Roles.valueOf(decodedJWT.getClaim("role").asString()); + Long id = decodedJWT.getClaim("id").asLong(); + if (webSocketConnections.getRoleToStateToToken().containsKey(role)) { + Iterator tempStateIterator = webSocketConnections.getRoleToStateToToken().get(role).keySet().iterator(); + while (tempStateIterator.hasNext()) { + String tempState = tempStateIterator.next(); + tempTokenIterator = webSocketConnections.getRoleToStateToToken().get(role).get(tempState).iterator(); + while (tempTokenIterator.hasNext()) { + String tempToken = tempTokenIterator.next(); + try { + tempdecodedJWT = jwtAuthProvider.getDecoded(tempToken); + Long tempId = tempdecodedJWT.getClaim("id").asLong(); + Roles tempRole = Roles.valueOf(tempdecodedJWT.getClaim("role").asString()); + if (sourceId.equals(tempId) && sourceRole.equals(tempRole)) + tempTokenIterator.remove(); + } catch (JWTVerificationException e) { + tempStateIterator.remove(); + } + } + } + if (webSocketConnections.getRoleToStateToToken().get(role).containsKey(STATE_CONNECTED)) { + webSocketConnections.getRoleToStateToToken().get(role).get(STATE_CONNECTED) + .add(sourceToken); + } else { + HashSet set = new HashSet<>(); + set.add(sourceToken); + webSocketConnections.getRoleToStateToToken().get(role).put(STATE_CONNECTED, set); + } + } else { + HashSet set = new HashSet<>(); + set.add(sourceToken); + Map> map = new HashMap<>(); + map.put(STATE_CONNECTED, set); + webSocketConnections.getRoleToStateToToken().put(role, map); + } + + if (webSocketConnections.getRoleToIdToToken().containsKey(role)) { + webSocketConnections.getRoleToIdToToken().get(role). + put(id, sourceToken); + + } else { + webSocketConnections.getRoleToIdToToken().computeIfAbsent( + role, + t -> new HashMap<>() + ).put(id, sourceToken); + } + + logger.info("added the token " + webSocketConnections.getSessionIdToToken()); + logger.info("added the session " + webSocketConnections.getTokenToSessionId()); + logger.info("added the state map" + webSocketConnections.getRoleToStateToToken()); + logger.info("this is the role to id to token: " + webSocketConnections.getRoleToIdToToken()); + sendTextMessage(session, tempWebsocketMessage.setItems("addedToken", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } catch (JWTVerificationException e) { + logger.error("JWTVerificationException occuered"); + sendTextMessage(session, tempWebsocketMessage.setItems("setToken :Invalid JWT token", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } catch (Exception e) { + logger.error("Some errror occured" + e); + sendTextMessage(session, tempWebsocketMessage.setItems("Some ERROR", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + + } + + private void handleConnectEvent(WebSocketSession sourceSession, WebSocketMessage socketMessage) + throws IOException { + /* + * - when patient sends to connect (initiates the call) token to token set must + * be updated or set accordingly + * - check for available counsellor and update the token to token set + * - based on the result reply the patient and counsellor + */ + String destToken = webSocketConnections.getRoleToIdToToken() + .get(Roles.valueOf(socketMessage.getDestination())) + .get(Long.parseLong(socketMessage.getData())); + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + Long id = getIdFromToken(sourceToken); + if (destToken != null) { + updateTheSate(destToken, STATE_CONNECTED, STATE_INCALL); + updateTheSate(webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + STATE_CONNECTED, + STATE_INCALL); + + addTokenToTokenSet( + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + destToken, + getRoleFromToken(destToken)); + addTokenToTokenSet( + destToken, + webSocketConnections.getSessionIdToToken().get(sourceSession.getId()), + getRoleFromToken(webSocketConnections.getSessionIdToToken().get(sourceSession.getId())) + ); + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("Connected", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + sendTextMessage(sessions.get( + webSocketConnections.getTokenToSessionId().get(destToken)), + tempWebsocketMessage.setItems("NewConnection:" + id, "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } else { + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("NotAvailable", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + } + + private Roles getRoleFromToken(String token) { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + + return Roles.valueOf(decodedJWT.getClaim("role").asString()); + } + + private Long getIdFromToken(String token) { + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + + return decodedJWT.getClaim("id").asLong(); + } + + private void addTokenToTokenSet(String sourceToken, String destToken, Roles role) { + webSocketConnections.getTokenToRoleToToken().computeIfAbsent( + sourceToken, k -> new HashMap<>()).put(role, destToken); + } + + private void updateTheSate(String token, String FromSTATE, String ToSTATE) { + System.out.println("inside the updateTheState: " + token); + System.out.println(FromSTATE + " :::> " + ToSTATE); + System.out.println("this is the RoleToStateToToken :: " + webSocketConnections.getRoleToStateToToken()); + DecodedJWT decodedJWT = jwtAuthProvider.getDecoded(token); + Roles role = Roles.valueOf(decodedJWT.getClaim("role").asString()); + webSocketConnections.getRoleToStateToToken().get(role).get(FromSTATE).remove(token); + webSocketConnections.getRoleToStateToToken().get(role).computeIfAbsent( + ToSTATE, + k -> new HashSet<>()).add(token); + } + + private String getAvailableCounsellorToken() { + if (webSocketConnections.getRoleToStateToToken().containsKey(Roles.ROLE_COUNSELLOR) + && webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).containsKey(STATE_CONNECTED) + && !webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).get(STATE_CONNECTED) + .isEmpty()) { + return webSocketConnections.getRoleToStateToToken().get(Roles.ROLE_COUNSELLOR).get(STATE_CONNECTED) + .iterator().next(); + } else { + return null; + } + } + + private void forwardMessage(WebSocketSession sourceSession, WebSocketMessage socketMessage) throws IOException { + System.out.println("this is token to Role to Token " + webSocketConnections.getTokenToRoleToToken()); + /* + * - when the message needs to be forwarded + * - check for the token to token set and send accordingly + */ + String sourceToken = webSocketConnections.getSessionIdToToken().get(sourceSession.getId()); + if (!webSocketConnections.getTokenToRoleToToken().containsKey(sourceToken) + || webSocketConnections.getTokenToRoleToToken().get(sourceToken).isEmpty()) { + sendTextMessage(sourceSession, + tempWebsocketMessage.setItems("DestinationNotConnected", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + + String destToken = webSocketConnections.getTokenToRoleToToken() + .get(sourceToken) + .get( + Roles.valueOf( + socketMessage.getDestination() + ) + ); + String destSessionId = webSocketConnections.getTokenToSessionId().get(destToken); + socketMessage.setToken(""); + sendTextMessage(sessions.get(destSessionId), socketMessage.toString()); + sendTextMessage(sourceSession, tempWebsocketMessage.setItems("forwardSuccess", "reply", "", socketMessage.getSource(), socketMessage.getDestination()).toString()); + } + + private void sendTextMessage(WebSocketSession session, String payload) throws IOException { + if (session != null && session.isOpen()) { + session.sendMessage(new TextMessage(payload)); + System.out.println("Sending this message: " + payload); + } else { + logger.warn("Attempted to send message to a closed session: {}", payload); + } + } + + @Override + public void afterConnectionEstablished(@Nullable WebSocketSession session) { + if (session != null) { + sessions.put(session.getId(), session); + } + } +} \ No newline at end of file diff --git a/Spring_Server/src/main/resources/application.properties b/Spring_Server/src/main/resources/application.properties new file mode 100644 index 0000000..f417714 --- /dev/null +++ b/Spring_Server/src/main/resources/application.properties @@ -0,0 +1,27 @@ +spring.datasource.url=jdbc:mysql://localhost:3306/drvolte +spring.datasource.username=root +spring.datasource.password=otageri +spring.jpa.hibernate.ddl-auto=update +server.address=192.168.216.8 +#HTTP port +http.port=80 +server.port=443 +server.ssl.key-store=keystore.p12 +server.ssl.key-store-password=784512963 +server.ssl.keyStoreType=PKCS12 +server.ssl.keyAlias=tomcat +#logging.level.root=warn +spring.data.rest.base-path=springdatarest +spring.data.rest.default-page-size=100 +# Application properties for Java Mail Sender +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username=hemantkumarcpersonal@gmail.com +spring.mail.password=qiylmvimrqwpgnov +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +# Application properties for Uploading / Downloading files +spring.servlet.multipart.enabled=true +spring.servlet.multipart.max-file-size=10MB +spring.servlet.multipart.file-size-threshold=10KB +spring.servlet.multipart.max-request-size=15MB \ No newline at end of file diff --git a/Spring_Server/src/main/resources/data.sql b/Spring_Server/src/main/resources/data.sql new file mode 100644 index 0000000..f6e8a8e --- /dev/null +++ b/Spring_Server/src/main/resources/data.sql @@ -0,0 +1 @@ +insert into users (username, password, enabled) values('admin', '{noop}admin', true); \ No newline at end of file diff --git a/Spring_Server/src/main/resources/schema.sql b/Spring_Server/src/main/resources/schema.sql new file mode 100644 index 0000000..c0303b8 --- /dev/null +++ b/Spring_Server/src/main/resources/schema.sql @@ -0,0 +1,12 @@ +create table users( + username varchar(50) not null primary key, + password varchar(50) not null, + enabled boolean not null +); + +create table authorities ( + username varchar(50) not null, + authority varchar(50) not null, + constraint foreign key(username) references users(username) +); +create unique index ix_auth_username on authorities (username,authority); \ No newline at end of file diff --git a/Spring_Server/src/test/java/com/drvolte/spring_server/SpringServerApplicationTests.java b/Spring_Server/src/test/java/com/drvolte/spring_server/SpringServerApplicationTests.java new file mode 100644 index 0000000..c7233ca --- /dev/null +++ b/Spring_Server/src/test/java/com/drvolte/spring_server/SpringServerApplicationTests.java @@ -0,0 +1,13 @@ +package com.drvolte.spring_server; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SpringServerApplicationTests { + + @Test + void contextLoads() { + } + +}