Compare commits

..

9 commits

14 changed files with 142 additions and 27 deletions

3
.env
View file

@ -2,9 +2,6 @@ VITE_BACKEND=http://localhost:4320/api/
# VITE_BACKEND=https://ocboapps.davaocity.gov.ph/esign-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_PESO=
VITE_HEADID=276

3
.gitignore vendored
View file

@ -25,7 +25,8 @@ dist-ssr
*.sw?
# environment variables
.env
.env.local
/backend/.env
# jetbrains setting folder
.idea/

View file

@ -4,15 +4,10 @@ import (
"database/sql"
"log"
"net/http"
// "crypto/rand"
// "crypto/rsa"
// "crypto/x509"
// "encoding/base64"
// "encoding/pem"
// "errors"
"os"
"ocbo-esign-backend/middleware"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
_ "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", func(c *gin.Context) {
router.POST("/api/post-registration", middleware.TokenChecker(), func(c *gin.Context) {
type RegistrationData struct {
Data int `json:"data"`
Data2 string `json:"data2"`

View 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()
}
}

View file

@ -18,6 +18,7 @@
"dayjs": "^1.11.19",
"gsap": "^3.13.0",
"jimp": "^1.6.0",
"jsencrypt": "^3.5.4",
"jspdf": "^3.0.3",
"jspdf-barcode": "^1.0.2",
"nanostores": "^1.0.1",

8
pnpm-lock.yaml generated
View file

@ -35,6 +35,9 @@ importers:
jimp:
specifier: ^1.6.0
version: 1.6.0
jsencrypt:
specifier: ^3.5.4
version: 3.5.4
jspdf:
specifier: ^3.0.3
version: 3.0.3
@ -1262,6 +1265,9 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
jsencrypt@3.5.4:
resolution: {integrity: sha512-kNjfYEMNASxrDGsmcSQh/rUTmcoRfSUkxnAz+MMywM8jtGu+fFEZ3nJjHM58zscVnwR0fYmG9sGkTDjqUdpiwA==}
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@ -2926,6 +2932,8 @@ snapshots:
js-tokens@4.0.0: {}
jsencrypt@3.5.4: {}
jsesc@3.1.0: {}
json5@2.2.3: {}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -127,28 +127,28 @@ export default () => {
const getopdetails = async (applicationNo: string) => {
const op = await ofetch(API + 'get-opdetails-electrical/' + applicationNo, { parseResponse: JSON.parse })
setAssessor(op.result7[0])
setLocation(op.result5[0])
setType(op.result6[0])
setDateOp(dayjs(op.result10[0]).format('MMMM DD, YYYY'))
setApplicationId(op.result11[0])
// setAssessorId(op.result12[0])
setTotalOp(calculateTotal(op.result9))
setLocation(op.result[0])
setType(op.result2[0])
setAssessor(op.result3[0])
setTotalOp(calculateTotal(op.result4))
setDateOp(dayjs(op.result5[0]).format('MMMM DD, YYYY'))
setApplicationId(op.result6[0])
// setAssessorId(op.result12[0])
// setDescriptionList(op.result8)
// setAmountList(op.result9)
// setDateOpList(op.result10)
// calculateAmounts()
getPrintDetails(op.result11[0])
getPrintDetailsFees(op.result11[0])
getPrintDetails(op.result6[0])
getPrintDetailsFees(op.result6[0])
getSignatureImage(employeeId())
const approversignId = await geteSignId(276)
getApprovedDate(approversignId, applicationNo)
// const assessorId = await getEmployeeId(op.result7[0])
// const assessorsignId = await geteSignId(assessorId)
getAssessedDate(op.result11[0])
getAssessedDate(op.result6[0])
}
const calculateTotal = (list: number[]) => {

View 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
}

View file

@ -6,9 +6,9 @@ export default async (api: string, value?: any) => {
try {
let fetch
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 {
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
return result

View file

@ -6,9 +6,9 @@ export default async (api: string, value?: any) => {
let fetch
try {
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 {
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