Compare commits
9 commits
4348fac56c
...
79a3e508dc
| Author | SHA1 | Date | |
|---|---|---|---|
| 79a3e508dc | |||
| 91a8f03749 | |||
| 0fba045794 | |||
| 3dc0eabba0 | |||
| 8cad050867 | |||
| 2837601606 | |||
| 57da00befa | |||
| 882e387f98 | |||
| ba551938d3 |
14 changed files with 142 additions and 27 deletions
3
.env
3
.env
|
|
@ -2,9 +2,6 @@ VITE_BACKEND=http://localhost:4320/api/
|
||||||
# VITE_BACKEND=https://ocboapps.davaocity.gov.ph/esign-server/api/
|
# VITE_BACKEND=https://ocboapps.davaocity.gov.ph/esign-server/api/
|
||||||
# VITE_BACKEND=http://192.168.7.163/server/api/
|
# VITE_BACKEND=http://192.168.7.163/server/api/
|
||||||
|
|
||||||
VITE_SECRET_KEY="_q]e88#^vfHYZUwO@CI%r=VNsIW8EohK"
|
|
||||||
VITE_IV="vLXE!H~M&*u-1)bB"
|
|
||||||
|
|
||||||
VITE_HEAD=ARCH. KHASHAYAR L. TOGHYANI
|
VITE_HEAD=ARCH. KHASHAYAR L. TOGHYANI
|
||||||
VITE_PESO=₱
|
VITE_PESO=₱
|
||||||
VITE_HEADID=276
|
VITE_HEADID=276
|
||||||
|
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -25,7 +25,8 @@ dist-ssr
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
# environment variables
|
# environment variables
|
||||||
.env
|
.env.local
|
||||||
|
/backend/.env
|
||||||
|
|
||||||
# jetbrains setting folder
|
# jetbrains setting folder
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,10 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
// "crypto/rand"
|
|
||||||
// "crypto/rsa"
|
|
||||||
// "crypto/x509"
|
|
||||||
// "encoding/base64"
|
|
||||||
// "encoding/pem"
|
|
||||||
// "errors"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"ocbo-esign-backend/middleware"
|
||||||
|
|
||||||
"github.com/gin-contrib/cors"
|
"github.com/gin-contrib/cors"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
|
@ -982,8 +977,7 @@ func connect() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// router.POST("/api/post-registration", middleware.tokenChecker, func(c *gin.Context) {
|
router.POST("/api/post-registration", middleware.TokenChecker(), func(c *gin.Context) {
|
||||||
router.POST("/api/post-registration", func(c *gin.Context) {
|
|
||||||
type RegistrationData struct {
|
type RegistrationData struct {
|
||||||
Data int `json:"data"`
|
Data int `json:"data"`
|
||||||
Data2 string `json:"data2"`
|
Data2 string `json:"data2"`
|
||||||
|
|
|
||||||
102
backend/middleware/tokenChecker.go
Normal file
102
backend/middleware/tokenChecker.go
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decrypt(encrypted string) (string, error) {
|
||||||
|
err := godotenv.Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error loading .env file")
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey := os.Getenv("PRIVATE_KEY")
|
||||||
|
|
||||||
|
cipherText, err := base64.StdEncoding.DecodeString(encrypted)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("cannot decode encrypted text")
|
||||||
|
}
|
||||||
|
|
||||||
|
block, _ := pem.Decode([]byte(privateKey))
|
||||||
|
if block == nil {
|
||||||
|
return "", errors.New("private key error")
|
||||||
|
}
|
||||||
|
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
result, err := rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TokenChecker() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
token := c.GetHeader("OCBO-Token")
|
||||||
|
start := strings.Index(token, "ocbo=") + len("ocbo=")
|
||||||
|
end := strings.LastIndex(token, "token")
|
||||||
|
|
||||||
|
if token == "" {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "The request is missing an OCBO Token"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if start == -1 || end == -1 || start >= end {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token format"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
extractedToken := token[start:end]
|
||||||
|
extractedToken = strings.ReplaceAll(extractedToken, "~", "/")
|
||||||
|
|
||||||
|
decrypted, err := decrypt(extractedToken)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token Value"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(decrypted, "-")
|
||||||
|
requested := parts[2]
|
||||||
|
requestedNum, _ := strconv.Atoi(requested)
|
||||||
|
expiration := parts[3]
|
||||||
|
expirationNum, _ := strconv.Atoi(expiration)
|
||||||
|
|
||||||
|
unix := strconv.FormatInt(time.Now().UTC().Unix(), 10)
|
||||||
|
unixNum, _ := strconv.Atoi(unix)
|
||||||
|
|
||||||
|
if requestedNum > expirationNum {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid OCBO Token Value"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if unixNum > expirationNum {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "OCBO Token Expired"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
"jimp": "^1.6.0",
|
"jimp": "^1.6.0",
|
||||||
|
"jsencrypt": "^3.5.4",
|
||||||
"jspdf": "^3.0.3",
|
"jspdf": "^3.0.3",
|
||||||
"jspdf-barcode": "^1.0.2",
|
"jspdf-barcode": "^1.0.2",
|
||||||
"nanostores": "^1.0.1",
|
"nanostores": "^1.0.1",
|
||||||
|
|
|
||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
|
@ -35,6 +35,9 @@ importers:
|
||||||
jimp:
|
jimp:
|
||||||
specifier: ^1.6.0
|
specifier: ^1.6.0
|
||||||
version: 1.6.0
|
version: 1.6.0
|
||||||
|
jsencrypt:
|
||||||
|
specifier: ^3.5.4
|
||||||
|
version: 3.5.4
|
||||||
jspdf:
|
jspdf:
|
||||||
specifier: ^3.0.3
|
specifier: ^3.0.3
|
||||||
version: 3.0.3
|
version: 3.0.3
|
||||||
|
|
@ -1262,6 +1265,9 @@ packages:
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
jsencrypt@3.5.4:
|
||||||
|
resolution: {integrity: sha512-kNjfYEMNASxrDGsmcSQh/rUTmcoRfSUkxnAz+MMywM8jtGu+fFEZ3nJjHM58zscVnwR0fYmG9sGkTDjqUdpiwA==}
|
||||||
|
|
||||||
jsesc@3.1.0:
|
jsesc@3.1.0:
|
||||||
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
|
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
@ -2926,6 +2932,8 @@ snapshots:
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
|
jsencrypt@3.5.4: {}
|
||||||
|
|
||||||
jsesc@3.1.0: {}
|
jsesc@3.1.0: {}
|
||||||
|
|
||||||
json5@2.2.3: {}
|
json5@2.2.3: {}
|
||||||
|
|
|
||||||
BIN
src/assets/security/rsa/backend/private.pem.cpt
Normal file
BIN
src/assets/security/rsa/backend/private.pem.cpt
Normal file
Binary file not shown.
BIN
src/assets/security/rsa/backend/public.pem.cpt
Normal file
BIN
src/assets/security/rsa/backend/public.pem.cpt
Normal file
Binary file not shown.
BIN
src/assets/security/rsa/frontend/private.pem.cpt
Normal file
BIN
src/assets/security/rsa/frontend/private.pem.cpt
Normal file
Binary file not shown.
BIN
src/assets/security/rsa/frontend/public.pem.cpt
Normal file
BIN
src/assets/security/rsa/frontend/public.pem.cpt
Normal file
Binary file not shown.
|
|
@ -127,28 +127,28 @@ export default () => {
|
||||||
|
|
||||||
const getopdetails = async (applicationNo: string) => {
|
const getopdetails = async (applicationNo: string) => {
|
||||||
const op = await ofetch(API + 'get-opdetails-electrical/' + applicationNo, { parseResponse: JSON.parse })
|
const op = await ofetch(API + 'get-opdetails-electrical/' + applicationNo, { parseResponse: JSON.parse })
|
||||||
setAssessor(op.result7[0])
|
setLocation(op.result[0])
|
||||||
setLocation(op.result5[0])
|
setType(op.result2[0])
|
||||||
setType(op.result6[0])
|
setAssessor(op.result3[0])
|
||||||
setDateOp(dayjs(op.result10[0]).format('MMMM DD, YYYY'))
|
setTotalOp(calculateTotal(op.result4))
|
||||||
setApplicationId(op.result11[0])
|
setDateOp(dayjs(op.result5[0]).format('MMMM DD, YYYY'))
|
||||||
// setAssessorId(op.result12[0])
|
setApplicationId(op.result6[0])
|
||||||
setTotalOp(calculateTotal(op.result9))
|
|
||||||
|
|
||||||
|
// setAssessorId(op.result12[0])
|
||||||
// setDescriptionList(op.result8)
|
// setDescriptionList(op.result8)
|
||||||
// setAmountList(op.result9)
|
// setAmountList(op.result9)
|
||||||
// setDateOpList(op.result10)
|
// setDateOpList(op.result10)
|
||||||
// calculateAmounts()
|
// calculateAmounts()
|
||||||
|
|
||||||
getPrintDetails(op.result11[0])
|
getPrintDetails(op.result6[0])
|
||||||
getPrintDetailsFees(op.result11[0])
|
getPrintDetailsFees(op.result6[0])
|
||||||
getSignatureImage(employeeId())
|
getSignatureImage(employeeId())
|
||||||
|
|
||||||
const approversignId = await geteSignId(276)
|
const approversignId = await geteSignId(276)
|
||||||
getApprovedDate(approversignId, applicationNo)
|
getApprovedDate(approversignId, applicationNo)
|
||||||
// const assessorId = await getEmployeeId(op.result7[0])
|
// const assessorId = await getEmployeeId(op.result7[0])
|
||||||
// const assessorsignId = await geteSignId(assessorId)
|
// const assessorsignId = await geteSignId(assessorId)
|
||||||
getAssessedDate(op.result11[0])
|
getAssessedDate(op.result6[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateTotal = (list: number[]) => {
|
const calculateTotal = (list: number[]) => {
|
||||||
|
|
|
||||||
12
src/utils/functions/encryptRsa.ts
Normal file
12
src/utils/functions/encryptRsa.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
const PUBLIC_KEY = import.meta.env.VITE_PUBLIC_KEY
|
||||||
|
import { JSEncrypt } from 'jsencrypt'
|
||||||
|
|
||||||
|
const enc = new JSEncrypt()
|
||||||
|
|
||||||
|
export default async (message: string) => {
|
||||||
|
enc.setPublicKey(PUBLIC_KEY)
|
||||||
|
const encrypted = enc.encrypt(message).toString()
|
||||||
|
const fixedEncrypted = encrypted.replace(/\//g, '~')
|
||||||
|
|
||||||
|
return fixedEncrypted
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,9 @@ export default async (api: string, value?: any) => {
|
||||||
try {
|
try {
|
||||||
let fetch
|
let fetch
|
||||||
if (!value) {
|
if (!value) {
|
||||||
fetch = await ofetch(API + api, { parseResponse: JSON.parse })
|
fetch = await ofetch(API + api, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
|
||||||
} else {
|
} else {
|
||||||
fetch = await ofetch(API + `${api}/${value}`, { parseResponse: JSON.parse })
|
fetch = await ofetch(API + `${api}/${value}`, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
|
||||||
}
|
}
|
||||||
const result = fetch.result
|
const result = fetch.result
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ export default async (api: string, value?: any) => {
|
||||||
let fetch
|
let fetch
|
||||||
try {
|
try {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
fetch = await ofetch(API + api, { parseResponse: JSON.parse })
|
fetch = await ofetch(API + api, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
|
||||||
} else {
|
} else {
|
||||||
fetch = await ofetch(API + `${api}/${value}`, { parseResponse: JSON.parse })
|
fetch = await ofetch(API + `${api}/${value}`, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch
|
return fetch
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue