├── README.md └── demo ├── HELP.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── Controller │ │ │ ├── ContentController.java │ │ │ ├── RegistrationController.java │ │ │ └── VerificationController.java │ │ │ ├── DemoApplication.java │ │ │ ├── Model │ │ │ ├── MyAppUser.java │ │ │ ├── MyAppUserRepository.java │ │ │ └── MyAppUserService.java │ │ │ ├── Security │ │ │ └── SecurityConfig.java │ │ │ ├── service │ │ │ └── EmailService.java │ │ │ └── utils │ │ │ └── JwtTokenUtil.java │ └── resources │ │ ├── application.yml │ │ ├── public │ │ └── error │ │ │ └── 404.html │ │ ├── static │ │ ├── css │ │ │ └── style.css │ │ └── js │ │ │ └── signup.js │ │ └── templates │ │ ├── index.html │ │ ├── login.html │ │ └── signup.html └── test │ └── java │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.java └── target ├── classes ├── application.yml ├── com │ └── example │ │ └── demo │ │ ├── Controller │ │ ├── ContentController.class │ │ └── RegistrationController.class │ │ ├── DemoApplication.class │ │ ├── Model │ │ ├── MyAppUser.class │ │ ├── MyAppUserRepository.class │ │ └── MyAppUserService.class │ │ └── Security │ │ └── SecurityConfig.class ├── public │ └── error │ │ └── 404.html ├── static │ ├── css │ │ └── style.css │ └── js │ │ └── signup.js └── templates │ ├── index.html │ ├── login.html │ └── signup.html └── test-classes └── com └── example └── demo └── DemoApplicationTests.class /README.md: -------------------------------------------------------------------------------- 1 | # springbootBackend -------------------------------------------------------------------------------- /demo/HELP.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.3.0/maven-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.3.0/maven-plugin/reference/html/#build-image) 9 | * [Spring Web](https://docs.spring.io/spring-boot/docs/3.3.0/reference/htmlsingle/index.html#web) 10 | * [Spring Security](https://docs.spring.io/spring-boot/docs/3.3.0/reference/htmlsingle/index.html#web.security) 11 | * [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.3.0/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data) 12 | * [Java Mail Sender](https://docs.spring.io/spring-boot/docs/3.3.0/reference/htmlsingle/index.html#io.email) 13 | 14 | ### Guides 15 | The following guides illustrate how to use some features concretely: 16 | 17 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) 18 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) 19 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) 20 | * [Securing a Web Application](https://spring.io/guides/gs/securing-web/) 21 | * [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/) 22 | * [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/) 23 | * [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) 24 | 25 | -------------------------------------------------------------------------------- /demo/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.1 23 | # 24 | # Optional ENV vars 25 | # ----------------- 26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source 27 | # MVNW_REPOURL - repo url base for downloading maven distribution 28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output 30 | # ---------------------------------------------------------------------------- 31 | 32 | set -euf 33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x 34 | 35 | # OS specific support. 36 | native_path() { printf %s\\n "$1"; } 37 | case "$(uname)" in 38 | CYGWIN* | MINGW*) 39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" 40 | native_path() { cygpath --path --windows "$1"; } 41 | ;; 42 | esac 43 | 44 | # set JAVACMD and JAVACCMD 45 | set_java_home() { 46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched 47 | if [ -n "${JAVA_HOME-}" ]; then 48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 49 | # IBM's JDK on AIX uses strange locations for the executables 50 | JAVACMD="$JAVA_HOME/jre/sh/java" 51 | JAVACCMD="$JAVA_HOME/jre/sh/javac" 52 | else 53 | JAVACMD="$JAVA_HOME/bin/java" 54 | JAVACCMD="$JAVA_HOME/bin/javac" 55 | 56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then 57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 59 | return 1 60 | fi 61 | fi 62 | else 63 | JAVACMD="$( 64 | 'set' +e 65 | 'unset' -f command 2>/dev/null 66 | 'command' -v java 67 | )" || : 68 | JAVACCMD="$( 69 | 'set' +e 70 | 'unset' -f command 2>/dev/null 71 | 'command' -v javac 72 | )" || : 73 | 74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then 75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 76 | return 1 77 | fi 78 | fi 79 | } 80 | 81 | # hash string like Java String::hashCode 82 | hash_string() { 83 | str="${1:-}" h=0 84 | while [ -n "$str" ]; do 85 | char="${str%"${str#?}"}" 86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) 87 | str="${str#?}" 88 | done 89 | printf %x\\n $h 90 | } 91 | 92 | verbose() { :; } 93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } 94 | 95 | die() { 96 | printf %s\\n "$1" >&2 97 | exit 1 98 | } 99 | 100 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties 101 | while IFS="=" read -r key value; do 102 | case "${key-}" in 103 | distributionUrl) distributionUrl="${value-}" ;; 104 | distributionSha256Sum) distributionSha256Sum="${value-}" ;; 105 | esac 106 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" 107 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" 108 | 109 | case "${distributionUrl##*/}" in 110 | maven-mvnd-*bin.*) 111 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ 112 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in 113 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; 114 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; 115 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; 116 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;; 117 | *) 118 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 119 | distributionPlatform=linux-amd64 120 | ;; 121 | esac 122 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" 123 | ;; 124 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; 125 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; 126 | esac 127 | 128 | # apply MVNW_REPOURL and calculate MAVEN_HOME 129 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 130 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" 131 | distributionUrlName="${distributionUrl##*/}" 132 | distributionUrlNameMain="${distributionUrlName%.*}" 133 | distributionUrlNameMain="${distributionUrlNameMain%-bin}" 134 | MAVEN_HOME="$HOME/.m2/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" 135 | 136 | exec_maven() { 137 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : 138 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" 139 | } 140 | 141 | if [ -d "$MAVEN_HOME" ]; then 142 | verbose "found existing MAVEN_HOME at $MAVEN_HOME" 143 | exec_maven "$@" 144 | fi 145 | 146 | case "${distributionUrl-}" in 147 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; 148 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; 149 | esac 150 | 151 | # prepare tmp dir 152 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then 153 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } 154 | trap clean HUP INT TERM EXIT 155 | else 156 | die "cannot create temp dir" 157 | fi 158 | 159 | mkdir -p -- "${MAVEN_HOME%/*}" 160 | 161 | # Download and Install Apache Maven 162 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 163 | verbose "Downloading from: $distributionUrl" 164 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 165 | 166 | # select .zip or .tar.gz 167 | if ! command -v unzip >/dev/null; then 168 | distributionUrl="${distributionUrl%.zip}.tar.gz" 169 | distributionUrlName="${distributionUrl##*/}" 170 | fi 171 | 172 | # verbose opt 173 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' 174 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v 175 | 176 | # normalize http auth 177 | case "${MVNW_PASSWORD:+has-password}" in 178 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; 179 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; 180 | esac 181 | 182 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then 183 | verbose "Found wget ... using wget" 184 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" 185 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then 186 | verbose "Found curl ... using curl" 187 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" 188 | elif set_java_home; then 189 | verbose "Falling back to use Java to download" 190 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" 191 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" 192 | cat >"$javaSource" <<-END 193 | public class Downloader extends java.net.Authenticator 194 | { 195 | protected java.net.PasswordAuthentication getPasswordAuthentication() 196 | { 197 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); 198 | } 199 | public static void main( String[] args ) throws Exception 200 | { 201 | setDefault( new Downloader() ); 202 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); 203 | } 204 | } 205 | END 206 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java 207 | verbose " - Compiling Downloader.java ..." 208 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" 209 | verbose " - Running Downloader.java ..." 210 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" 211 | fi 212 | 213 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 214 | if [ -n "${distributionSha256Sum-}" ]; then 215 | distributionSha256Result=false 216 | if [ "$MVN_CMD" = mvnd.sh ]; then 217 | echo "Checksum validation is not supported for maven-mvnd." >&2 218 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 219 | exit 1 220 | elif command -v sha256sum >/dev/null; then 221 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then 222 | distributionSha256Result=true 223 | fi 224 | elif command -v shasum >/dev/null; then 225 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then 226 | distributionSha256Result=true 227 | fi 228 | else 229 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 230 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 231 | exit 1 232 | fi 233 | if [ $distributionSha256Result = false ]; then 234 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 235 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 236 | exit 1 237 | fi 238 | fi 239 | 240 | # unzip and move 241 | if command -v unzip >/dev/null; then 242 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" 243 | else 244 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" 245 | fi 246 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" 247 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" 248 | 249 | clean || : 250 | exec_maven "$@" 251 | -------------------------------------------------------------------------------- /demo/mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM https://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.1 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 83 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 84 | 85 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 86 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 87 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 88 | exit $? 89 | } 90 | 91 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 92 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 93 | } 94 | 95 | # prepare tmp dir 96 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 97 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 98 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 99 | trap { 100 | if ($TMP_DOWNLOAD_DIR.Exists) { 101 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 102 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 103 | } 104 | } 105 | 106 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 107 | 108 | # Download and Install Apache Maven 109 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 110 | Write-Verbose "Downloading from: $distributionUrl" 111 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 112 | 113 | $webclient = New-Object System.Net.WebClient 114 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 115 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 116 | } 117 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 118 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 119 | 120 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 121 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 122 | if ($distributionSha256Sum) { 123 | if ($USE_MVND) { 124 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 125 | } 126 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 127 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 128 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 129 | } 130 | } 131 | 132 | # unzip and move 133 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 134 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 135 | try { 136 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 137 | } catch { 138 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 139 | Write-Error "fail to move MAVEN_HOME" 140 | } 141 | } finally { 142 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 143 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 144 | } 145 | 146 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 147 | -------------------------------------------------------------------------------- /demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.0 9 | 10 | 11 | com.example 12 | demo 13 | 0.0.1-SNAPSHOT 14 | demo 15 | Demo project for Spring Boot 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-mail 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-security 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | 38 | org.postgresql 39 | postgresql 40 | runtime 41 | 42 | 43 | org.projectlombok 44 | lombok 45 | true 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-starter-test 50 | test 51 | 52 | 53 | org.springframework.security 54 | spring-security-test 55 | test 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-thymeleaf 60 | 61 | 62 | io.jsonwebtoken 63 | jjwt-api 64 | 0.11.5 65 | 66 | 67 | io.jsonwebtoken 68 | jjwt-impl 69 | 0.11.5 70 | runtime 71 | 72 | 73 | io.jsonwebtoken 74 | jjwt-jackson 75 | 0.11.5 76 | runtime 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | org.projectlombok 89 | lombok 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Controller/ContentController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class ContentController { 8 | 9 | @GetMapping("/req/login") 10 | public String login(){ 11 | return "login"; 12 | } 13 | 14 | @GetMapping("/req/signup") 15 | public String signup(){ 16 | return "signup"; 17 | } 18 | @GetMapping("/index") 19 | public String home(){ 20 | return "index"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Controller/RegistrationController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.example.demo.Model.MyAppUser; 12 | import com.example.demo.Model.MyAppUserRepository; 13 | import com.example.demo.service.EmailService; 14 | import com.example.demo.utils.JwtTokenUtil; 15 | 16 | @RestController 17 | public class RegistrationController { 18 | 19 | @Autowired 20 | private MyAppUserRepository myAppUserRepository; 21 | 22 | @Autowired 23 | private PasswordEncoder passwordEncoder; 24 | 25 | @Autowired 26 | private EmailService emailService; 27 | 28 | 29 | @PostMapping(value = "/req/signup", consumes = "application/json") 30 | public ResponseEntity createUser(@RequestBody MyAppUser user){ 31 | 32 | MyAppUser existingAppUser = myAppUserRepository.findByEmail(user.getEmail()); 33 | 34 | if(existingAppUser != null){ 35 | if(existingAppUser.isVerified()){ 36 | return new ResponseEntity<>("User Already exist and Verified.",HttpStatus.BAD_REQUEST); 37 | }else{ 38 | String verificationToken = JwtTokenUtil.generateToken(existingAppUser.getEmail()); 39 | existingAppUser.setVerficationToken(verificationToken); 40 | myAppUserRepository.save(existingAppUser); 41 | //Send Email Code 42 | emailService.sendVerificationEmail(existingAppUser.getEmail(), verificationToken); 43 | return new ResponseEntity<>("Verification Email resent. Check your inbox",HttpStatus.OK); 44 | } 45 | } 46 | user.setPassword(passwordEncoder.encode(user.getPassword())); 47 | String vericationToken =JwtTokenUtil.generateToken(user.getEmail()); 48 | user.setVerficationToken(vericationToken); 49 | myAppUserRepository.save(user); 50 | //Send Email Code 51 | emailService.sendVerificationEmail(user.getEmail(), vericationToken); 52 | 53 | return new ResponseEntity<>("Registration successfull! Please Verify your Email", HttpStatus.OK); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Controller/VerificationController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.example.demo.Model.MyAppUser; 11 | import com.example.demo.Model.MyAppUserRepository; 12 | import com.example.demo.utils.JwtTokenUtil; 13 | 14 | @RestController 15 | public class VerificationController { 16 | 17 | @Autowired 18 | private MyAppUserRepository myAppUserRepository; 19 | 20 | @Autowired 21 | private JwtTokenUtil jwtUtil; 22 | 23 | @GetMapping("/req/signup/verify") 24 | public ResponseEntity verifyEmail(@RequestParam("token") String token) { 25 | String emailString = jwtUtil.extractEmail(token); 26 | MyAppUser user = myAppUserRepository.findByEmail(emailString); 27 | if (user == null || user.getVerficationToken() == null) { 28 | return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Token Expired!"); 29 | } 30 | 31 | if (!jwtUtil.validateToken(token) || !user.getVerficationToken().equals(token)) { 32 | return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Token Expired!"); 33 | } 34 | user.setVerficationToken(null); 35 | user.setVerified(true); 36 | myAppUserRepository.save(user); 37 | 38 | return ResponseEntity.status(HttpStatus.CREATED).body("Email successfully verified!"); 39 | } 40 | 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Model/MyAppUser.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Model; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.GenerationType; 7 | import jakarta.persistence.Id; 8 | 9 | @Entity 10 | public class MyAppUser { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.AUTO) 14 | private Long id; 15 | private String username; 16 | private String email; 17 | private String password; 18 | private String verficationToken; 19 | private boolean isVerified; 20 | 21 | @Column(name = "reset_token") 22 | private String resetToken; 23 | 24 | public String getVerficationToken() { 25 | return verficationToken; 26 | } 27 | public void setVerficationToken(String verficationToken) { 28 | this.verficationToken = verficationToken; 29 | } 30 | public boolean isVerified() { 31 | return isVerified; 32 | } 33 | public void setVerified(boolean isVerified) { 34 | this.isVerified = isVerified; 35 | } 36 | public String getResetToken() { 37 | return resetToken; 38 | } 39 | public void setResetToken(String resetToken) { 40 | this.resetToken = resetToken; 41 | } 42 | public Long getId() { 43 | return id; 44 | } 45 | public void setId(Long id) { 46 | this.id = id; 47 | } 48 | public String getUsername() { 49 | return username; 50 | } 51 | public void setUsername(String username) { 52 | this.username = username; 53 | } 54 | public String getEmail() { 55 | return email; 56 | } 57 | public void setEmail(String email) { 58 | this.email = email; 59 | } 60 | public String getPassword() { 61 | return password; 62 | } 63 | public void setPassword(String password) { 64 | this.password = password; 65 | } 66 | 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Model/MyAppUserRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Model; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public interface MyAppUserRepository extends JpaRepository{ 10 | 11 | Optional findByUsername(String username); 12 | 13 | MyAppUser findByEmail(String email); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Model/MyAppUserService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Model; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.userdetails.User; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import lombok.AllArgsConstructor; 13 | 14 | @Service 15 | @AllArgsConstructor 16 | public class MyAppUserService implements UserDetailsService{ 17 | 18 | @Autowired 19 | private MyAppUserRepository repository; 20 | 21 | @Override 22 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 23 | 24 | Optional user = repository.findByUsername(username); 25 | if (user.isPresent()) { 26 | var userObj = user.get(); 27 | return User.builder() 28 | .username(userObj.getUsername()) 29 | .password(userObj.getPassword()) 30 | .build(); 31 | }else{ 32 | throw new UsernameNotFoundException(username); 33 | } 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/Security/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.Security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.authentication.AuthenticationProvider; 7 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; 11 | import org.springframework.security.core.userdetails.UserDetailsService; 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | import org.springframework.security.web.SecurityFilterChain; 15 | 16 | import com.example.demo.Model.MyAppUserService; 17 | 18 | import lombok.AllArgsConstructor; 19 | 20 | @Configuration 21 | @AllArgsConstructor 22 | @EnableWebSecurity 23 | public class SecurityConfig { 24 | 25 | @Autowired 26 | private final MyAppUserService appUserService; 27 | 28 | 29 | @Bean 30 | public UserDetailsService userDetailsService(){ 31 | return appUserService; 32 | } 33 | 34 | @Bean 35 | public AuthenticationProvider authenticationProvider(){ 36 | DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); 37 | provider.setUserDetailsService(appUserService); 38 | provider.setPasswordEncoder(passwordEncoder()); 39 | return provider; 40 | } 41 | 42 | @Bean 43 | public PasswordEncoder passwordEncoder(){ 44 | return new BCryptPasswordEncoder(); 45 | } 46 | 47 | @Bean 48 | public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{ 49 | return httpSecurity 50 | .csrf(AbstractHttpConfigurer::disable) 51 | .formLogin(httpForm ->{ 52 | httpForm.loginPage("/req/login").permitAll(); 53 | httpForm.defaultSuccessUrl("/index"); 54 | 55 | }) 56 | 57 | 58 | .authorizeHttpRequests(registry ->{ 59 | registry.requestMatchers("/req/**","/css/**","/js/**").permitAll(); 60 | registry.anyRequest().authenticated(); 61 | }) 62 | .build(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/service/EmailService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.mail.javamail.JavaMailSender; 6 | import org.springframework.mail.javamail.MimeMessageHelper; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 9 | 10 | import jakarta.mail.internet.MimeMessage; 11 | 12 | @Service 13 | public class EmailService { 14 | @Autowired 15 | private JavaMailSender mailSender; 16 | 17 | @Value("${spring.mail.username}") 18 | private String from; 19 | 20 | public void sendVerificationEmail(String email, String verificationToken) { 21 | String subject = "Email Verification"; 22 | String path = "/req/signup/verify"; 23 | String message = "Click the button below to verify your email address:"; 24 | sendEmail(email, verificationToken, subject, path, message); 25 | } 26 | 27 | 28 | public void sendForgotPasswordEmail(String email, String resetToken) { 29 | String subject = "Password Reset Request"; 30 | String path = "/req/reset-password"; 31 | String message = "Click the button below to reset your password:"; 32 | sendEmail(email, resetToken, subject, path, message); 33 | } 34 | 35 | 36 | private void sendEmail(String email, String token, String subject, String path, String message) { 37 | try { 38 | String actionUrl = ServletUriComponentsBuilder.fromCurrentContextPath() 39 | .path(path) 40 | .queryParam("token", token) 41 | .toUriString(); 42 | 43 | String content = """ 44 |
45 |

%s

46 |

%s

47 | Proceed 48 |

Or copy and paste this link into your browser:

49 |

%s

50 |

This is an automated message. Please do not reply.

51 |
52 | """.formatted(subject, message, actionUrl, actionUrl); 53 | 54 | MimeMessage mimeMessage = mailSender.createMimeMessage(); 55 | MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); 56 | 57 | helper.setTo(email); 58 | helper.setSubject(subject); 59 | helper.setFrom(from); 60 | helper.setText(content, true); 61 | mailSender.send(mimeMessage); 62 | 63 | } catch (Exception e) { 64 | System.err.println("Failed to send email: " + e.getMessage()); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /demo/src/main/java/com/example/demo/utils/JwtTokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.utils; 2 | 3 | import java.util.Date; 4 | 5 | import javax.crypto.SecretKey; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | import io.jsonwebtoken.JwtParser; 10 | import io.jsonwebtoken.Jwts; 11 | import io.jsonwebtoken.SignatureAlgorithm; 12 | import io.jsonwebtoken.security.Keys; 13 | 14 | @Component 15 | public class JwtTokenUtil { 16 | 17 | private final static SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); 18 | private final static long EXPIRATION_TIME = 86400000; 19 | 20 | public static String generateToken(String email) { 21 | return Jwts.builder() 22 | .setSubject(email) 23 | .setIssuedAt(new Date()) 24 | .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) 25 | .signWith(SECRET_KEY, SignatureAlgorithm.HS256) 26 | .compact(); 27 | } 28 | 29 | public boolean validateToken(String token) { 30 | return !isTokenExpired(token); 31 | } 32 | 33 | public String extractEmail(String token) { 34 | JwtParser jwtParser = Jwts.parserBuilder() 35 | .setSigningKey(SECRET_KEY) 36 | .build(); 37 | 38 | return jwtParser.parseClaimsJws(token) 39 | .getBody() 40 | .getSubject(); 41 | } 42 | 43 | private boolean isTokenExpired(String token) { 44 | return extractExpiration(token).before(new Date()); 45 | } 46 | 47 | private Date extractExpiration(String token) { 48 | JwtParser jwtParser = Jwts.parserBuilder() 49 | .setSigningKey(SECRET_KEY) 50 | .build(); 51 | 52 | return jwtParser.parseClaimsJws(token) 53 | .getBody() 54 | .getExpiration(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demo/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | error: 3 | include-message: always 4 | include-binding-errors: always 5 | 6 | spring: 7 | mail: 8 | host: smtp.gmail.com 9 | port: 587 10 | username: email@gmail.com 11 | password: password 12 | protocol: smtp 13 | properties: 14 | mail: 15 | smtp: 16 | auth: true 17 | starttls: 18 | enable: true 19 | datasource: 20 | password: 21 | url: jdbc:postgresql://localhost:5432/registration 22 | username: 23 | jpa: 24 | hibernate: 25 | ddl-auto: update 26 | properties: 27 | hibernate: 28 | dialect: org.hibernate.dialect.PostgreSQLDialect 29 | format_sql: true 30 | show-sql: true -------------------------------------------------------------------------------- /demo/src/main/resources/public/error/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 Not Found 7 | 31 | 32 | 33 |
34 |

404 Not Found

35 |

Sorry, the page you are looking for might be in another castle.

36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /demo/src/main/resources/static/css/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap'); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | font-family: 'Poppins', sans-serif; 8 | } 9 | 10 | body { 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | min-height: 100vh; 15 | background-image: url(https://user-images.githubusercontent.com/13468728/233847739-219cb494-c265-4554-820a-bd3424c59065.jpg); 16 | background-repeat: no-repeat; 17 | background-position: center; 18 | background-size: cover; 19 | } 20 | 21 | section { 22 | position: relative; 23 | max-width: 500px; /* Adjust the max-width as needed */ 24 | background-color: transparent; 25 | border: 2px solid rgba(255, 255, 255, 0.5); 26 | border-radius: 20px; 27 | backdrop-filter: blur(55px); 28 | display: flex; 29 | justify-content: center; 30 | align-items: center; 31 | padding: 2rem 3rem; 32 | transition: all 0.5s ease-in-out; 33 | } 34 | 35 | 36 | h1 { 37 | font-size: 2rem; 38 | color: #fff; 39 | text-align: center; 40 | } 41 | .inputbox { 42 | position: relative; 43 | margin: 20px 0; 44 | max-width: 550px; 45 | border-bottom: 2px solid #fff; 46 | transition: all 0.5s ease-in-out; 47 | } 48 | 49 | .inputbox input { 50 | width: 100%; 51 | height: 40px; 52 | background: transparent; 53 | border: none; 54 | outline: none; 55 | font-size: 1rem; 56 | padding: 0 35px 0 5px; 57 | color: #fff; 58 | } 59 | 60 | .inputbox ion-icon { 61 | position: absolute; 62 | right: 8px; 63 | color: #fff; 64 | font-size: 1.2rem; 65 | top: 12px; 66 | transition: all 0.5s ease-in-out; 67 | } 68 | 69 | 70 | .inputbox label { 71 | position: absolute; 72 | top: 50%; 73 | left: 5px; 74 | transform: translateY(-50%); 75 | color: #fff; 76 | font-size: 1rem; 77 | pointer-events: none; 78 | transition: all 0.5s ease-in-out; 79 | } 80 | 81 | input:focus ~ label, 82 | input:valid ~ label { 83 | top: -5px; 84 | font-size: 0.9rem; 85 | color: #a8a8a8; 86 | } 87 | 88 | button { 89 | width: 100%; 90 | height: 40px; 91 | border-radius: 40px; 92 | background-color: rgba(255, 255, 255, 1); 93 | border: none; 94 | outline: none; 95 | cursor: pointer; 96 | font-size: 1rem; 97 | font-weight: 600; 98 | transition: all 0.4s ease; 99 | } 100 | 101 | button:hover { 102 | background-color: rgba(255, 255, 255, 0.5); 103 | } 104 | 105 | .register { 106 | font-size: 0.9rem; 107 | color: #fff; 108 | text-align: center; 109 | margin: 25px 0 10px; 110 | transition: all 0.5s ease-in-out; 111 | } 112 | 113 | .register p a { 114 | text-decoration: none; 115 | color: #fff; 116 | font-weight: 600; 117 | transition: all 0.5s ease-in-out; 118 | } 119 | 120 | .register p a:hover { 121 | text-decoration: underline; 122 | color: #a8a8a8; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /demo/src/main/resources/static/js/signup.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | const signupForm = document.querySelector('section'); 3 | signupForm.style.opacity = 0; 4 | 5 | setTimeout(() => { 6 | signupForm.style.transition = 'opacity 1s ease-in-out'; 7 | signupForm.style.opacity = 1; 8 | }, 500); 9 | 10 | const signupButton = document.querySelector('button'); 11 | signupButton.addEventListener('click', function () { 12 | const emailInput = document.querySelector('input[type="email"]'); 13 | const passwordInput = document.querySelector('input[type="password"]'); 14 | const confirmPasswordInput = document.querySelector('input[type="password"][name="confirm-password"]'); 15 | 16 | // Check for a valid email and password (you can add your validation logic here) 17 | const isValid = emailInput.checkValidity() && passwordInput.checkValidity() && confirmPasswordInput.checkValidity(); 18 | 19 | if (!isValid) { 20 | signupForm.classList.add('shake'); 21 | 22 | setTimeout(() => { 23 | signupForm.classList.remove('shake'); 24 | }, 1000); 25 | } 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /demo/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | My Home Page 7 | 53 | 54 | 55 |
56 |

Welcome to My Home Page

57 |
58 | 64 |
65 |

About Me

66 |

This is a paragraph about me. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque nisl ut sapien interdum, nec ullamcorper velit dapibus. Sed ac vestibulum libero, nec tempor felis.

67 |

Services

68 |

These are the services I offer. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque nisl ut sapien interdum, nec ullamcorper velit dapibus. Sed ac vestibulum libero, nec tempor felis.

69 |
70 |
71 |

Footer Content © 2024

72 |
73 | 74 | 75 | -------------------------------------------------------------------------------- /demo/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Login 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |

Login

17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 | 29 |
30 |
31 |

Forget Password ?

32 |
33 | 34 |
35 |

Don't have a account ? Register!!

36 |
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /demo/src/main/resources/templates/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Signup Form 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

Sign Up

15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 | 26 |
27 | 28 | 29 | 30 |
31 |
32 | 33 | 34 | 35 |
36 | 37 |
38 |

Already have an account? Log In

39 |
40 |
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /demo/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class DemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /demo/target/classes/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | error: 3 | include-message: always 4 | include-binding-errors: always 5 | 6 | spring: 7 | datasource: 8 | password: 9 | url: jdbc:postgresql://localhost:5432/registration 10 | username: 11 | jpa: 12 | hibernate: 13 | ddl-auto: update 14 | properties: 15 | hibernate: 16 | dialect: org.hibernate.dialect.PostgreSQLDialect 17 | format_sql: true 18 | show-sql: true -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Controller/ContentController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Controller/ContentController.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Controller/RegistrationController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Controller/RegistrationController.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/DemoApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/DemoApplication.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Model/MyAppUser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Model/MyAppUser.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Model/MyAppUserRepository.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Model/MyAppUserRepository.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Model/MyAppUserService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Model/MyAppUserService.class -------------------------------------------------------------------------------- /demo/target/classes/com/example/demo/Security/SecurityConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/classes/com/example/demo/Security/SecurityConfig.class -------------------------------------------------------------------------------- /demo/target/classes/public/error/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 Not Found 7 | 31 | 32 | 33 |
34 |

404 Not Found

35 |

Sorry, the page you are looking for might be in another castle.

36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /demo/target/classes/static/css/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap'); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | font-family: 'Poppins', sans-serif; 8 | } 9 | 10 | body { 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | min-height: 100vh; 15 | background-image: url(https://user-images.githubusercontent.com/13468728/233847739-219cb494-c265-4554-820a-bd3424c59065.jpg); 16 | background-repeat: no-repeat; 17 | background-position: center; 18 | background-size: cover; 19 | } 20 | 21 | section { 22 | position: relative; 23 | max-width: 500px; /* Adjust the max-width as needed */ 24 | background-color: transparent; 25 | border: 2px solid rgba(255, 255, 255, 0.5); 26 | border-radius: 20px; 27 | backdrop-filter: blur(55px); 28 | display: flex; 29 | justify-content: center; 30 | align-items: center; 31 | padding: 2rem 3rem; 32 | transition: all 0.5s ease-in-out; 33 | } 34 | 35 | 36 | h1 { 37 | font-size: 2rem; 38 | color: #fff; 39 | text-align: center; 40 | } 41 | .inputbox { 42 | position: relative; 43 | margin: 20px 0; 44 | max-width: 550px; 45 | border-bottom: 2px solid #fff; 46 | transition: all 0.5s ease-in-out; 47 | } 48 | 49 | .inputbox input { 50 | width: 100%; 51 | height: 40px; 52 | background: transparent; 53 | border: none; 54 | outline: none; 55 | font-size: 1rem; 56 | padding: 0 35px 0 5px; 57 | color: #fff; 58 | } 59 | 60 | .inputbox ion-icon { 61 | position: absolute; 62 | right: 8px; 63 | color: #fff; 64 | font-size: 1.2rem; 65 | top: 12px; 66 | transition: all 0.5s ease-in-out; 67 | } 68 | 69 | 70 | .inputbox label { 71 | position: absolute; 72 | top: 50%; 73 | left: 5px; 74 | transform: translateY(-50%); 75 | color: #fff; 76 | font-size: 1rem; 77 | pointer-events: none; 78 | transition: all 0.5s ease-in-out; 79 | } 80 | 81 | input:focus ~ label, 82 | input:valid ~ label { 83 | top: -5px; 84 | font-size: 0.9rem; 85 | color: #a8a8a8; 86 | } 87 | 88 | button { 89 | width: 100%; 90 | height: 40px; 91 | border-radius: 40px; 92 | background-color: rgba(255, 255, 255, 1); 93 | border: none; 94 | outline: none; 95 | cursor: pointer; 96 | font-size: 1rem; 97 | font-weight: 600; 98 | transition: all 0.4s ease; 99 | } 100 | 101 | button:hover { 102 | background-color: rgba(255, 255, 255, 0.5); 103 | } 104 | 105 | .register { 106 | font-size: 0.9rem; 107 | color: #fff; 108 | text-align: center; 109 | margin: 25px 0 10px; 110 | transition: all 0.5s ease-in-out; 111 | } 112 | 113 | .register p a { 114 | text-decoration: none; 115 | color: #fff; 116 | font-weight: 600; 117 | transition: all 0.5s ease-in-out; 118 | } 119 | 120 | .register p a:hover { 121 | text-decoration: underline; 122 | color: #a8a8a8; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /demo/target/classes/static/js/signup.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | const signupForm = document.querySelector('section'); 3 | signupForm.style.opacity = 0; 4 | 5 | setTimeout(() => { 6 | signupForm.style.transition = 'opacity 1s ease-in-out'; 7 | signupForm.style.opacity = 1; 8 | }, 500); 9 | 10 | const signupButton = document.querySelector('button'); 11 | signupButton.addEventListener('click', function () { 12 | const emailInput = document.querySelector('input[type="email"]'); 13 | const passwordInput = document.querySelector('input[type="password"]'); 14 | const confirmPasswordInput = document.querySelector('input[type="password"][name="confirm-password"]'); 15 | 16 | // Check for a valid email and password (you can add your validation logic here) 17 | const isValid = emailInput.checkValidity() && passwordInput.checkValidity() && confirmPasswordInput.checkValidity(); 18 | 19 | if (!isValid) { 20 | signupForm.classList.add('shake'); 21 | 22 | setTimeout(() => { 23 | signupForm.classList.remove('shake'); 24 | }, 1000); 25 | } 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /demo/target/classes/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | My Home Page 7 | 53 | 54 | 55 |
56 |

Welcome to My Home Page

57 |
58 | 64 |
65 |

About Me

66 |

This is a paragraph about me. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque nisl ut sapien interdum, nec ullamcorper velit dapibus. Sed ac vestibulum libero, nec tempor felis.

67 |

Services

68 |

These are the services I offer. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque nisl ut sapien interdum, nec ullamcorper velit dapibus. Sed ac vestibulum libero, nec tempor felis.

69 |
70 |
71 |

Footer Content © 2024

72 |
73 | 74 | 75 | -------------------------------------------------------------------------------- /demo/target/classes/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Login 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |

Login

17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 | 29 |
30 |
31 |

Forget Password ?

32 |
33 | 34 |
35 |

Don't have a account ? Register!!

36 |
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /demo/target/classes/templates/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Signup Form 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

Sign Up

15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 | 26 |
27 | 28 | 29 | 30 |
31 |
32 | 33 | 34 | 35 |
36 | 37 |
38 |

Already have an account? Log In

39 |
40 |
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /demo/target/test-classes/com/example/demo/DemoApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alanlands1/springbootBackend/6621816cddfb99f9bfe24f9f14b9f463c55d4a3c/demo/target/test-classes/com/example/demo/DemoApplicationTests.class --------------------------------------------------------------------------------