Browse Source

first commit

master
yoganandhank 1 year ago
commit
edb6fd7e53
  1. 2
      .gitattributes
  2. 33
      .gitignore
  3. 19
      .mvn/wrapper/maven-wrapper.properties
  4. 259
      mvnw
  5. 149
      mvnw.cmd
  6. 73
      pom.xml
  7. 13
      src/main/java/com/gcc/crslogs/CrslogsApplication.java
  8. 61
      src/main/java/com/gcc/crslogs/configuration/AppConfig.java
  9. 284
      src/main/java/com/gcc/crslogs/controller/ApiController.java
  10. 43
      src/main/java/com/gcc/crslogs/controller/MainController.java
  11. 152
      src/main/java/com/gcc/crslogs/service/BirthAndDeathDetailsService.java
  12. 12
      src/main/resources/application-dev.properties
  13. 11
      src/main/resources/application-prod.properties
  14. 1
      src/main/resources/application.properties
  15. 1151
      src/main/resources/templates/modules/crslogspages/birthanddeath.html
  16. 809
      src/main/resources/templates/modules/crslogspages/loginpage.html
  17. 13
      src/test/java/com/gcc/crslogs/CrslogsApplicationTests.java

2
.gitattributes

@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

33
.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/

19
.mvn/wrapper/maven-wrapper.properties

@ -0,0 +1,19 @@
# 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
#
# http://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.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

259
mvnw

@ -0,0 +1,259 @@
#!/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
#
# http://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.3.2
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
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"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

149
mvnw.cmd

@ -0,0 +1,149 @@
<# : batch portion
@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 http://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.3.2
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@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 @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
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."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

73
pom.xml

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gcc</groupId>
<artifactId>crslogs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>crslogs</name>
<description>crs_logs</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

13
src/main/java/com/gcc/crslogs/CrslogsApplication.java

@ -0,0 +1,13 @@
package com.gcc.crslogs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CrslogsApplication {
public static void main(String[] args) {
SpringApplication.run(CrslogsApplication.class, args);
}
}

61
src/main/java/com/gcc/crslogs/configuration/AppConfig.java

@ -0,0 +1,61 @@
package com.gcc.crslogs.configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
private String title;
private String baseUrl;
private String getOtpUrl;
private String erpUrl;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getGetOtpUrl() {
return getOtpUrl;
}
public void setGetOtpUrl(String getOtpUrl) {
this.getOtpUrl = getOtpUrl;
}
public String getErpUrl() {
return erpUrl;
}
public void setErpUrl(String erpUrl) {
this.erpUrl = erpUrl;
}
}

284
src/main/java/com/gcc/crslogs/controller/ApiController.java

@ -0,0 +1,284 @@
package com.gcc.crslogs.controller;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gcc.crslogs.configuration.AppConfig;
import com.gcc.crslogs.service.BirthAndDeathDetailsService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
@RestController
@RequestMapping("/crs/api")
public class ApiController {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private AppConfig appConfig;
@Autowired
private BirthAndDeathDetailsService birthAndDeathDetailsService;
private final RestTemplate restTemplate = new RestTemplate();
/*///////////////// otp configuration /////////////////////*/
@GetMapping(value = "/sendOTP")
public String sendOtp(HttpServletRequest request, @RequestParam String mobile) {
// Create an ObjectMapper instance
ObjectMapper objectMapper = new ObjectMapper();
// Check if mobile number is already registered
//List<WasteRegistration> registrations = wasteregistrationrepo.findByMobileNo(mobile);
// Create a response map
Map<String, Object> response = new HashMap<>();
// if (registrations.isEmpty()) {
// // If mobile number is not registered
// response.put("status", "NOT_REGISTERED");
// response.put("mobile", mobile); // Return the mobile number
// try {
// return objectMapper.writeValueAsString(response); // Use the instance to convert map to JSON string
// } catch (Exception e) {
// // Handle JSON conversion error
// return "{\"status\": \"ERROR\", \"message\": \"Could not convert response to JSON.\"}";
// }
// }
String MobileNo=mobile;
System.out.print("\n MobileNo---:"+mobile);
Random rand = new Random();
int otp = rand.nextInt(90000) + 10000;
//int otp= 22222;
System.out.print("\n otp---:"+otp);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy%20HH:mm");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
//String generatedToken = "Welcome to GCC! Your OTP for C%26D waste collectors Registration process is "+otp;
//String generatedToken = "Welcome to GCC "+otp+" is your OTP for gcc QR System";
String generatedToken = "Welcome to GCC! Your OTP for Birth and Death Certificate login is " + otp;
//String generatedToken = "Welcome to GCC! Your OTP for C and D waste collectors Registration process is " + otp;
// String key="qxg4mklD";
String key="pfTEYN6H";
String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407174687453240990";
//String urlString = "https://tmegov.onex-aura.com/api/sms?from=GCCCRP&key=pfTEYN6H&sender=GCCCRP&to=9360777472&body=Welcome%20to%20GCC!%20Your%20OTP%20for%20C%26D%20waste%20collectors%20Registration%20process%20is%20"+otp+"&entityid=1401572690000011081&templateid=1407172959127552127";
//String urlString= appConfig.getGetOtpUrl()+"from=GCCCRP&key="+key+"&sender=GCCCRP&to="+MobileNo+"&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407168250479102852";
// String urlString=appConfig.getGetOtpUrl()+"user=GCCtrans&authkey=92kOC1RBGBIws&sender=GCCCRP&mobile="+MobileNo+"&text="+generatedToken+"&rpt=1&summary=1&output=json&entityid=1401572690000011081&templateid=1407168250479102852";
System.out.print("\n urlString---: "+urlString);
String bodyMessage = "";
try {
RestTemplate restTemplate = new RestTemplate();
String Response = restTemplate.getForObject(urlString, String.class);
bodyMessage=Response;
System.out.println("\n bodyMessage"+bodyMessage);
System.out.println("OTP sent successfully!");
} catch (Exception e) {
System.out.print("ERROR---: "+e);
bodyMessage = "Error";
}
HttpSession session = request.getSession();
session.setAttribute("otp", otp);
return bodyMessage;
}
@GetMapping(value = "/verifyOTP")
public Map<String, String> verifyOtp(HttpServletRequest request, @RequestParam String otp,
@RequestParam String mobNo,@RequestParam String flag) {
HttpSession session = request.getSession();
Map<String, String> response = new HashMap<>();
Map<String, Object> userDetails;
try {
Integer session_otp = (Integer) session.getAttribute("otp");
System.out.println("session_otp---:" + session_otp);
Integer entered_otp = Integer.parseInt(otp);
if (session_otp != null && session_otp.equals(entered_otp)) {
System.out.println("Entered OTP Correct");
if("1".equals(flag)) {
userDetails = birthAndDeathDetailsService.getUserDetails(mobNo);
if(userDetails != null) {
session.setAttribute("userId", userDetails.get("user_id"));
session.setAttribute("userName", userDetails.get("user_name"));
session.setAttribute("verifiedotp", "success");
response.put("userName", (String) userDetails.get("user_name"));
}
System.out.println("userId---:" + userDetails.get("user_id")+"\nuserName:"+userDetails.get("user_name"));
}
response.put("status", "Success");
} else {
//System.out.println("Incorrect OTP. Please enter correct OTP.");
session.setAttribute("verifiedotp", "error");
response.put("status", "Error");
response.put("message", "Incorrect OTP.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid OTP format: " + otp);
response.put("status", "Error");
response.put("message", "Invalid OTP format.");
} catch (Exception e) {
System.out.println("Error verifying OTP: " + e.getMessage());
response.put("status", "Error");
response.put("message", "Internal server error.");
}
return response;
}
@GetMapping("/birth-details")
public ResponseEntity<?> fetchBirthCertificateSecurely(
@RequestParam String dob,
@RequestParam String sex,
@RequestParam(required = false) String regno,
@RequestParam(required = false) String childname,
@RequestParam(required = false) String fathername,
@RequestParam(required = false) String mothername) {
if (dob.isEmpty() || sex.isEmpty()) {
Map<String, Object> error = new HashMap<>();
error.put("status", false);
error.put("message", "DOB and Sex are mandatory.");
return ResponseEntity.badRequest().body(error);
}
try {
Map<String, Object> result = birthAndDeathDetailsService.fetchBirthCertificate(dob, sex, regno, childname, fathername, mothername);
return ResponseEntity.ok(result);
} catch (Exception e) {
e.printStackTrace();
Map<String, Object> error = new HashMap<>();
error.put("status", false);
error.put("message", "Something went wrong: " + e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
@GetMapping("/death-details")
public ResponseEntity<?> fetchDeathCertificateSecurely(
@RequestParam String dod,
@RequestParam String sex,
@RequestParam(required = false) String regno,
@RequestParam(required = false) String personname,
@RequestParam(required = false) String fathername,
@RequestParam(required = false) String mothername) {
if (dod.isEmpty() || sex.isEmpty()) {
Map<String, Object> error = new HashMap<>();
error.put("status", false);
error.put("message", "DOB and Sex are mandatory.");
return ResponseEntity.badRequest().body(error);
}
try {
Map<String, Object> result = birthAndDeathDetailsService.fetchDeathCertificate(dod, sex, regno, personname, fathername, mothername);
return ResponseEntity.ok(result);
} catch (Exception e) {
e.printStackTrace();
Map<String, Object> error = new HashMap<>();
error.put("status", false);
error.put("message", "Something went wrong: " + e.getMessage());
return ResponseEntity.status(500).body(error);
}
}
@PostMapping("/saveNewUser")
public ResponseEntity<?> saveNewUser (@RequestParam String user_name, @RequestParam String user_address, @RequestParam String user_mobile) {
// Convert name to uppercase before saving
String upperCaseName = user_name.toUpperCase();
return birthAndDeathDetailsService.saveNewUser(upperCaseName, user_address, user_mobile);
}
@PostMapping("/checkUser")
public ResponseEntity<Map<String, Object>> checkUser(@RequestParam String mobile) {
Map<String, Object> response = new HashMap<>();
try {
boolean userExists = birthAndDeathDetailsService.isUserRegistered(mobile);
response.put("exists", userExists);
return ResponseEntity.ok(response);
} catch (Exception e) {
response.put("error", "An error occurred while checking user registration.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
}
@PostMapping("/saveCertificateLogs")
public ResponseEntity<?> saveCertificateLogs(HttpServletRequest request, @RequestParam String regNo, @RequestParam String eventDate,
@RequestParam String Url, @RequestParam String service){
HttpSession session = request.getSession();
int userid = 0 ;
try{
userid = (int) session.getAttribute("userId");
}catch(Exception e){
e.printStackTrace();
}
return birthAndDeathDetailsService.saveCertificateLogs(regNo, eventDate, Url, service, userid);
}
// @PostMapping("/checkUser")
// public ResponseEntity<?> checkUser(@RequestParam String user_mobile) {
// boolean exists = birthAndDeathDetailsService.isUserExists(user_mobile);
// if (exists) {
// return ResponseEntity.ok().body("User already registered.");
// } else {
// return ResponseEntity.ok().body("User not registered.");
// }
// }
}

43
src/main/java/com/gcc/crslogs/controller/MainController.java

@ -0,0 +1,43 @@
package com.gcc.crslogs.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
@Controller
@RequestMapping(value = { "/crs" })
public class MainController {
@GetMapping(value = { "", "/", "/loginpage" })
public String requestform(Model model) {
return "modules/crslogspages/loginpage";
}
@GetMapping("/birthanddeath")
public String birthform(HttpServletRequest request, Model model) {
HttpSession session = request.getSession();
//System.out.println("username.."+session.getAttribute("userName"));
String username = (String) session.getAttribute("userName");
if (username==null || username.isEmpty()) {
return "modules/crslogspages/loginpage";
}
// User is logged in
return "modules/crslogspages/birthanddeath";
}
@GetMapping("/logout")
public String logoutForm(HttpServletRequest request) {
HttpSession session = request.getSession();
session.invalidate();
return "modules/crslogspages/loginpage";
}
}

152
src/main/java/com/gcc/crslogs/service/BirthAndDeathDetailsService.java

@ -0,0 +1,152 @@
package com.gcc.crslogs.service;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@Service
public class BirthAndDeathDetailsService {
@Autowired
private final RestTemplate restTemplate;
@Autowired
private JdbcTemplate jdbcTemplate;
public BirthAndDeathDetailsService(RestTemplateBuilder builder) {
this.restTemplate = builder.build();
}
public Map<String, Object> fetchBirthCertificate(String dob, String sex, String regno, String childName, String fatherName, String motherName) throws Exception {
Map<String, String> params = new LinkedHashMap(); // keep order
params.put("regno", regno != null ? regno : "");
params.put("sex", sex);
params.put("dob", dob);
params.put("childname", childName != null ? childName : "");
params.put("fathername", fatherName != null ? fatherName : "");
params.put("mothername", motherName != null ? motherName : "");
ObjectMapper mapper = new ObjectMapper();
String serviceInput = mapper.writeValueAsString(params);
// Final raw URL — NOT encoded
String BirthCertificateapiUrl = "https://chennaicorporation.gov.in/gcc/Api/BirthCertificate_json.jsp?serviceinput=" + serviceInput;
//System.out.println("⏩ Raw JSON: " + serviceInput);
//System.out.println("🌐 FINAL RAW URL: " + BirthCertificateapiUrl);
HttpHeaders headers = new HttpHeaders();
headers.set("User-Agent", "Mozilla/5.0");
HttpEntity<String> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(BirthCertificateapiUrl, HttpMethod.GET, entity, String.class);
//System.out.println("✅ API Raw Response: " + response.getBody());
return mapper.readValue(response.getBody(), new TypeReference<Map<String, Object>>() {});
}
public Map<String, Object> fetchDeathCertificate(String dod, String sex, String regno, String personName, String fatherName, String motherName) throws Exception {
@SuppressWarnings("rawtypes")
Map<String, String> params = new LinkedHashMap(); // keep order
params.put("regno", regno != null ? regno : "");
params.put("sex", sex);
params.put("dod", dod);
params.put("personname", personName != null ? personName : "");
params.put("fathername", fatherName != null ? fatherName : "");
params.put("mothername", motherName != null ? motherName : "");
ObjectMapper mapper = new ObjectMapper();
String serviceInput = mapper.writeValueAsString(params);
// Final raw URL — NOT encoded
String DeathCertificateapiUrl = "https://chennaicorporation.gov.in/gcc/Api/DeathCertificate_json.jsp?serviceinput=" + serviceInput;
//System.out.println("⏩ Raw JSON: " + serviceInput);
//System.out.println("🌐 FINAL RAW URL: " + DeathCertificateapiUrl);
HttpHeaders headers = new HttpHeaders();
headers.set("User-Agent", "Mozilla/5.0");
HttpEntity<String> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(DeathCertificateapiUrl, HttpMethod.GET, entity, String.class);
//System.out.println("✅ API Raw Response: " + response.getBody());
return mapper.readValue(response.getBody(), new TypeReference<Map<String, Object>>() {});
}
@Transactional
public ResponseEntity<?> saveNewUser(String user_name, String user_address, String user_mobile) {
Map<String, Object> result = new HashMap();
String sql = "INSERT INTO users (user_name, user_address, user_mobile) VALUES (?, ?, ?)";
try {
jdbcTemplate.update(sql, user_name, user_address, user_mobile);
result.put("message", "New User Saved Sucessfully");
result.put("data", "Success");
return ResponseEntity.ok(result);
} catch (Exception e) {
e.printStackTrace();
result.put("message", "Error");
result.put("Error", "Failed to save new user: " + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
public boolean isUserRegistered(String mobile) {
String sql = "SELECT COUNT(*) FROM users WHERE user_mobile = ?";
Integer count = jdbcTemplate.queryForObject(sql, new Object[]{mobile}, Integer.class);
return count != null && count > 0;
}
public ResponseEntity<?> saveCertificateLogs(String regNo, String eventDate, String url, String service, int userid) {
String sql = "Insert into certificate_logs (regno, event_date, english_url, service, user_id) VALUES (?, ?, ?, ?, ?)";
Integer count = jdbcTemplate.update(sql, regNo, eventDate, url, service, userid);
return count != null && count > 0 ? ResponseEntity.ok(count) : ResponseEntity.notFound().build();
}
public Map<String,Object> getUserDetails(String mobNo) {
String sql = "Select * from users where user_mobile = ?";
return jdbcTemplate.queryForMap(sql, mobNo);
}
}

12
src/main/resources/application-dev.properties

@ -0,0 +1,12 @@
spring.application.name=crslogs
spring.datasource.url=jdbc:mysql://localhost:3306/crs_logs
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
server.port=8076
app.getOtpUrl=https://tmegov.onex-aura.com/api/sms?

11
src/main/resources/application-prod.properties

@ -0,0 +1,11 @@
spring.application.name=crslogs
spring.datasource.url=jdbc:mysql://gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306/crs_logs
spring.datasource.username=root
spring.datasource.password=gcc-facial-password
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
server.port=8076
app.getOtpUrl=https://tmegov.onex-aura.com/api/sms?

1
src/main/resources/application.properties

@ -0,0 +1 @@
spring.profiles.active=dev

1151
src/main/resources/templates/modules/crslogspages/birthanddeath.html
File diff suppressed because it is too large
View File

809
src/main/resources/templates/modules/crslogspages/loginpage.html

@ -0,0 +1,809 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GCC - Birth & Death</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Only load it once) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Popper.js (Required for Bootstrap 4) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<!-- SweetAlert JS (optional if you plan to use it) -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
/* Header Styling */
.header {
background-color: #134356;
padding: 10px 20px;
color: rgb(255, 255, 255);
font-family: Arial, sans-serif;
}
.header .logo img {
height: 60px;
}
.header .center-text {
text-align: center;
font-size: 24px;
}
.header .menu-btn {
background-color: transparent;
border: none;
font-size: 24px;
color: white;
}
.header .menu-btn:hover {
color: #ccc;
}
/* Menu Dropdown */
.menu-dropdown {
position: absolute;
top: 80px;
right: 20px;
background-color: #1d495a;
padding: 10px;
display: none;
flex-direction: column;
z-index: 1000; /* Add z-index to bring the menu above other elements */
}
.menu-dropdown a {
color: white;
margin-bottom: 5px;
text-decoration: none;
}
.menu-dropdown a:hover {
text-decoration: underline;
}
/* otp*/
.otp-input-box {
display: flex;
justify-content: center;
gap: 10px;
/* Adjust spacing between the inputs */
}
.otp-input {
width: 50px;
/* Width for a square input */
height: 50px;
/* Height for a square input */
font-size: 24px;
/* Make the digits larger */
text-align: center;
/* Center the digit inside the box */
border: 1px solid #ccc;
/* Optional: add a border */
border-radius: 5px;
/* Optional: rounded corners */
outline: none;
/* Remove default focus outline */
transition: border-color 0.3s ease;
}
.otp-input:focus {
border-color: #007bff;
/* Change border color on focus */
}
/* otp*/
/*send otp styles*/
.input-group .form-control {
border-right: 0;
/* Remove right border of the input to blend with the button */
}
.input-group-append .btn {
border-left: 0;
/* Remove left border of the button */
}
.bottom-container {
margin-bottom: 50px; /* Adjust as needed */
}
/* Mobile Specific Styling */
@media (max-width: 768px) {
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.center-text {
font-size: 18px !important;
flex-grow: 1;
text-align: center;
}
.menu-dropdown {
right: 0;
left: 0;
z-index: 1000; /* Add z-index to bring the menu above other elements */
}
}
.button-wrapper {
display: flex;
justify-content: center;
margin-top: 20px; /* adds space from the top */
}
#registersubmit {
background-color: #0c4f63;
border: none;
width: 150px; /* optional: set fixed width */
}
#submitBtn {
background-color: #0c4f63;
border: none;
width: 150px; /* optional: set fixed width */
}
</style>
</head>
<body style="background-color: #ebf1fa;">
<!-- Header Start-->
<header>
<div class="header d-flex justify-content-between align-items-center">
<!-- Left: Logo -->
<div class="logo">
<img src="https://gccservices.in/gcc/assets/images/logo.png" alt="Logo">
</div>
<!-- Center: Text -->
<div class="center-text">
GREATER CHENNAI CORPORATION
</div>
<!-- Right: Button for Menu -->
<div class="menu">
</div>
</div>
</header>
<!-- Header End-->
<main class="container mt-4">
<!-- First Card -->
<!-- Register Card -->
<!-- Register Card -->
<div class="card register-card mx-auto mt-5" style="max-width: 400px; background-color: rgba(44, 84, 103, 0.1); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid #ffffff40; display:none;">
<div class="card-body ">
<h4 class="text-center mb-4" style="color: #004865;"><strong>Birth And Death Registration</strong></h4>
<hr>
<!-- Name -->
<div class="form-group">
<label for="name">Name</label><span class="text-danger">*</span>
<input type="text" class="form-control " id="name" placeholder="Enter your name" oninput="this.value = this.value.replace(/[^a-zA-Z\s]/g, '')">
</div>
<!-- Phone -->
<div class="form-group">
<label for="phone">Mobile No</label><span class="text-danger">*</span>
<input type="text" class="form-control" id="phone" placeholder="Enter Mobile number" oninput="validatePhoneNumber(this)">
</div>
<!-- Address -->
<div class="form-group">
<label for="address">Address</label><span class="text-danger">*</span>
<textarea class="form-control" id="address" rows="2" placeholder="Enter your Address"></textarea>
</div>
<div class="button-wrapper">
<button type="submit" class="btn btn-primary" id="registersubmit">Register</button>
</div>
<div class="text-center mt-3 mb-2">
<label>
If you already have an account,
<a href="#" id="showLoginCardBtn">click here to login</a>.
</label>
</div>
</div>
</div>
<div class="card login-card mx-auto mt-5" style="max-width: 400px; background-color: rgba(44, 84, 103, 0.1); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid #ffffff40; " >
<div class="card-body ">
<h4 class="text-center mb-4" style="color: #004865;"><strong>Birth And Death Login</strong></h4>
<hr>
<!-- Phone -->
<div class="form-group">
<label for="phone">Mobile No</label>
<span class="text-danger">*</span>
<input type="text"
id="phoneNumber" class="form-control"
placeholder="Enter Mobile number"
oninput="validatePhoneNumber(this)">
</div>
<div class="button-wrapper">
<button type="submit" class="btn btn-primary" id="submitBtn">Login</button>
</div>
<div class="text-center mt-3 mb-2">
<label>
If you don't have an account,
<a href="#" id="showRegisterCardBtn">click here to Register</a>.
</label>
</div>
</div>
</div>
</main>
<!-- OTP Modal -->
<div class="modal fade" id="otpForm" tabindex="-1" role="dialog"
aria-labelledby="otpFormLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form action="" onsubmit="return verifyOtp(1); "> <!--1 mentioned for existing user login -->
<div class="modal-header">
<h6 class="modal-title m-0" id="exampleModalDefaultLabel">OTP
Login</h6>
<button type="button" class="close" data-bs-dismiss="modal"
aria-label="Close"
style="color: black; border: white; background-color: white;">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row ">
<div class="mb-3" style="text-align: center;">
<img src="https://gccservices.in/gcc/files/c_d/otp.png"
width="50%" alt="Mobileotp">
</div>
</div>
<div class="row d-flex justify-content-center align-items-center">
<div class="mb-0">
<h4>OTP Verification</h4>
<p class="text-mute">
Enter the OTP sent to <b class="text-info" id="mobilenotxt"></b>
</p>
<p class="text-danger" id="otperror"></p>
</div>
</div>
<div class="row d-flex justify-content-center align-items-center">
<div class="mb-3 ">
<div class="otp-input-box">
<input type="text" maxlength="1" class="otp-input" id="otp1"
required /> <input type="text" maxlength="1"
class="otp-input" id="otp2" required /> <input type="text"
maxlength="1" class="otp-input" id="otp3" required /> <input
type="text" maxlength="1" class="otp-input" id="otp4" required />
<input type="text" maxlength="1" class="otp-input" id="otp5"
required />
</div>
</div>
</div>
<div class="mb-3 text-center">
<div id="resend-containers">
<p class="mb-0">Didn't receive OTP?</p>
<p class="mb-0 text-info" id="resendlink"></p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" id="but">Verify
OTP</button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
const registerCard = document.querySelector(".register-card");
const loginCard = document.querySelector(".login-card");
function clearRegisterForm() {
document.getElementById("name").value = "";
document.getElementById("phone").value = "";
document.getElementById("address").value = "";
}
function clearLoginForm() {
document.getElementById("phoneNumber").value = "";
}
document.getElementById("showRegisterCardBtn").addEventListener("click", function (e) {
e.preventDefault();
clearLoginForm();
loginCard.style.display = "none";
registerCard.style.display = "block";
});
document.getElementById("showLoginCardBtn").addEventListener("click", function (e) {
e.preventDefault();
clearRegisterForm();
registerCard.style.display = "none";
loginCard.style.display = "block";
});
});
$(document).ready(function () {
// Show Login Card when "Login" is clicked from Register Card
$('#showLoginCardBtn').on('click', function (e) {
e.preventDefault();
$('.register-card').hide();
$('.login-card').show();
});
// Show Register Card when "Register" is clicked from Login Card
$('#showRegisterCardBtn').on('click', function (e) {
e.preventDefault();
$('.login-card').hide();
$('.register-card').show();
});
// When OTP modal is closed
$('#otpForm').on('hidden.bs.modal', function () {
// Clear all OTP input fields
$('.otp-input').val('');
// Clear OTP error message
$('#otperror').text('');
// Restart the countdown
startCountdown();
});
});
// phone number validation
function validatePhoneNumber(input) {
// Remove any non-numeric characters using regex
input.value = input.value.replace(/[^0-9]/g, '');
// Limit the input to 10 digits
if (input.value.length > 10) {
input.value = input.value.slice(0, 10);
}
}
$('#registersubmit').click(function (event) {
event.preventDefault();
const name = $('#name').val().trim();
const mobileNumber = $('#phone').val().trim();
const address = $('#address').val().trim();
if (!name) {
Swal.fire({ icon: 'warning', title: 'Missing Name', text: 'Please enter your name.' });
return;
}
if (!mobileNumber || mobileNumber.length !== 10) {
Swal.fire({ title: "Invalid Mobile Number", text: "Please enter a valid 10-digit mobile number.", icon: "error" });
return;
}
if (!address) {
Swal.fire({ icon: 'warning', title: 'Missing Address', text: 'Please enter your address.' });
return;
}
// Step 1: Check if user already exists
$.ajax({
type: "POST",
url: '/crs/api/checkUser',
data: { mobile: mobileNumber },
success: function (response) {
if (response.exists) {
Swal.fire({
title: "Already Registered",
text: "This mobile number is already registered. Please login.",
icon: "info"
});
} else {
// Step 2: Send OTP
sendOtp(mobileNumber);
// Step 3: Wait for user to manually click Verify inside OTP modal,
// and if successful, call verifyOtp with a callback
$('#but').off('click').on('click', function () {
verifyOtp(2,function () { // 2 is mentioned for new user registration
// Step 4: Save new user only after OTP success
$.ajax({
url: '/crs/api/saveNewUser',
type: 'POST',
data: {
user_name: name,
user_address: address,
user_mobile: mobileNumber
},
success: function () {
Swal.fire({
icon: 'success',
title: 'Registration Successful',
//text: 'Redirecting...'
}).then(() => {
$('#name').val('');
$('#phone').val('');
$('#address').val('');
window.location.href = "/crs/loginpage";
});
},
error: function (xhr) {
let message = 'An error occurred.';
if (xhr.responseJSON && xhr.responseJSON.message) {
message = xhr.responseJSON.message;
}
Swal.fire({ icon: 'error', title: 'Failed', text: message });
}
});
});
});
}
},
error: function () {
Swal.fire({
title: "Server Error",
text: "Unable to check user status.",
icon: "error"
});
}
});
});
$('#submitBtn').click(function (event) {
event.preventDefault();
let mobileNumber = $('#phoneNumber').val().trim();
if (!mobileNumber || mobileNumber.length !== 10) {
Swal.fire({
title: "Invalid Mobile Number",
text: "Please enter a valid 10-digit mobile number.",
icon: "error",
confirmButtonText: "OK",
allowOutsideClick: false
});
return;
}
// Step 1: Check if user exists
$.ajax({
type: "POST",
url: '/crs/api/checkUser',
data: { mobile: mobileNumber },
success: function (response) {
if (response.exists) {
// Step 2: Send OTP to registered user
sendOtp(mobileNumber);
// Step 3: Bind OTP verify for login
$('#but').off('click').on('click', function () {
verifyOtp(1, function () {
// Step 4: Redirect to birth & death page ONLY after OTP success
window.location.href = "/crs/birthanddeath";
});
});
} else {
// Not registered
Swal.fire({
title: "User Not Found",
text: "This mobile number is not registered. Please register to continue.",
icon: "warning",
confirmButtonText: "OK",
allowOutsideClick: false
}).then(() => {
window.location.reload(); // Optionally show registration card instead
});
}
},
error: function () {
Swal.fire({
title: "Server Error",
text: "Unable to check user status. Please try again later.",
icon: "error",
confirmButtonText: "OK"
});
}
});
});
function sendOtp(mobileNumber) {
Swal.fire({
title: 'Processing OTP...',
text: 'Please wait while we send the OTP.',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
let minDisplayTime = 5000;
let startTime = new Date().getTime();
$.ajax({
type: "GET",
url: '/crs/api/sendOTP',
data: { 'mobile': mobileNumber },
dataType: 'json',
success: function (response) {
let elapsedTime = new Date().getTime() - startTime;
let delay = Math.max(0, minDisplayTime - elapsedTime);
setTimeout(function () {
Swal.close();
console.log("OTP sent response:", response);
$('#mobilenotxt').html(mobileNumber);
$('#otpForm').modal({
backdrop: 'static',
keyboard: false
}).modal('show');
startCountdown();
}, delay);
},
error: function () {
Swal.fire({
title: "Server Error",
text: "There was an issue sending your OTP. Please try again later.",
icon: "error",
confirmButtonText: "OK"
});
}
});
}
function verifyOtp(flag, onSuccessCallback) {
//alert("inside line 849")
Swal.fire({
title: 'Verifying OTP...',
text: 'Please wait while we verify the OTP.',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
const minDisplayTime = 2000;
const startTime = new Date().getTime();
let otpValue = '';
$('.otp-input').each(function () {
otpValue += $(this).val();
});
const mobileNumber = $('#mobilenotxt').text().trim();
$.ajax({
type: "GET",
url: '/crs/api/verifyOTP',
data: {'otp': otpValue, 'mobNo': mobileNumber, 'flag': flag},
dataType: 'json',
success: function (response) {
console.log("response...",response);
if (response.userName) {
localStorage.setItem("userName", response.userName);
}
const elapsedTime = new Date().getTime() - startTime;
const delay = Math.max(0, minDisplayTime - elapsedTime);
setTimeout(function () {
Swal.close();
if (response.status === "Success") {
//alert("inside line 890 " + response.userName);
console.log("Welcome, " , response.userName);
Swal.fire({
title: "OTP Verified!",
text: "Your OTP has been successfully verified.",
icon: "success",
confirmButtonText: "OK",
allowOutsideClick: false
}).then(() => {
$('#otpForm').modal('hide');
//$('#sendOtpButton').hide();
$('#phoneNumber').prop('disabled', true);
$('#verifiedOTP').prop('disabled', false).css('display', 'block');
if (typeof onSuccessCallback === 'function') {
onSuccessCallback(); // ✅ Call the registration save logic here
}
/* if(flag==1){
window.location.href = "/birthanddeath";
}else{
window.location.href = "/loginpage";
} */
//saveDetails();
});
} else {
Swal.fire({
title: "OTP Incorrect",
text: "The OTP you entered is incorrect. Please try again.",
icon: "error",
confirmButtonText: "Retry"
});
}
}, delay);
},
error: function () {
Swal.fire({
title: "Verification Failed",
text: "There was an issue verifying your OTP. Please try again later.",
icon: "error"
});
}
});
return false;
}
// Declare the timeout variable globally
let resendTimeout = null;
// Countdown and resend handler
function startCountdown() {
// Clear any existing countdown interval
if (resendTimeout) {
clearInterval(resendTimeout);
resendTimeout = null;
}
let timeleft = 60;
$('#resendlink').html('Please wait.. <span id="countdown">60</span>s');
resendTimeout = setInterval(function () {
timeleft--;
$('#countdown').text(timeleft);
if (timeleft <= 0) {
clearInterval(resendTimeout);
resendTimeout = null; // Clear reference
$('#resendlink').html('<a href="#" id="resend-link" class="text-info" onclick="return resendOTP();">Resend OTP</a>');
}
}, 1000);
}
// Resend OTP logic
function resendOTP() {
const mobileNumber = $('#mobilenotxt').text().trim();
if (!mobileNumber || mobileNumber.length !== 10) return false;
$.ajax({
type: "GET",
url: '/crs/api/sendOTP',
data: { 'mobile': mobileNumber },
dataType: 'json',
success: function (response) {
Swal.fire({
title: "OTP Resent",
text: "A new OTP has been sent to your mobile.",
icon: "info",
confirmButtonText: "OK",
allowOutsideClick: false
}).then(() => {
// Clear all OTP input fields
for (let i = 1; i <= 5; i++) {
$(`#otp${i}`).val('');
}
startCountdown(); // Start countdown again if needed
});
},
error: function () {
Swal.fire({
title: "Error",
text: "Could not resend OTP. Please try again.",
icon: "error"
});
}
});
return false; // prevent default link behavior
}
// For OTP input box
$('.otp-input').on('keyup', function (e) {
var $this = $(this);
if ($this.val().length === 1) {
$this.next('.otp-input').focus();
}
if ($this.val().length === 0) {
$this.prev('.otp-input').focus();
}
});
</script>
</body>
</html>

13
src/test/java/com/gcc/crslogs/CrslogsApplicationTests.java

@ -0,0 +1,13 @@
package com.gcc.crslogs;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class CrslogsApplicationTests {
@Test
void contextLoads() {
}
}
Loading…
Cancel
Save