Compare commits

...

5 commits

8 changed files with 218 additions and 86 deletions

View file

@ -1,6 +1,6 @@
module ocbo-esign-backend
go 1.25.4
go 1.25.5
require (
github.com/gin-contrib/cors v1.7.6
@ -21,7 +21,7 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.29.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.19.0 // indirect
github.com/goccy/go-yaml v1.19.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect

View file

@ -11,8 +11,6 @@ github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gE
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/cors v1.7.6 h1:3gQ8GMzs1Ylpf70y8bMw4fVpycXIeX1ZemuSQIsnQQY=
@ -27,16 +25,14 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
github.com/go-playground/validator/v10 v10.29.0 h1:lQlF5VNJWNlRbRZNeOIkWElR+1LL/OuHcc0Kp14w1xk=
github.com/go-playground/validator/v10 v10.29.0/go.mod h1:D6QxqeMlgIPuT02L66f2ccrZ7AGgHkzKmmTMZhk/Kc4=
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.0 h1:EmkZ9RIsX+Uq4DYFowegAuJo8+xdX3T/2dwNPXbxEYE=
github.com/goccy/go-yaml v1.19.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/goccy/go-yaml v1.19.1 h1:3rG3+v8pkhRqoQ/88NYNMHYVGYztCOCIZ7UQhu7H+NE=
github.com/goccy/go-yaml v1.19.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -82,27 +78,17 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=
golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -1308,30 +1308,30 @@ func connect() {
"result": result,
})
case "check-qr":
var count int
err := db.QueryRow("SELECT COUNT(esignid) AS result FROM esign WHERE SUBSTR(signature, 36) = ?", data).Scan(&count)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
c.String(http.StatusBadRequest, err.Error())
return
}
if count > 0 {
err := db.QueryRow("SELECT IFNULL(e.employeename, '') AS result FROM esign es JOIN employee e ON es.employeeid = e.employeeid WHERE SUBSTR(signature, 36) = ?", data).Scan(&result)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
c.String(http.StatusBadRequest, err.Error())
return
}
// case "check-qr":
// var count int
// err := db.QueryRow("SELECT COUNT(esignid) AS result FROM esign WHERE SUBSTR(signature, 36) = ?", data).Scan(&count)
// if err != nil {
// c.AbortWithError(http.StatusBadRequest, err)
// c.String(http.StatusBadRequest, err.Error())
// return
// }
// if count > 0 {
// err := db.QueryRow("SELECT IFNULL(e.employeename, '') AS result FROM esign es JOIN employee e ON es.employeeid = e.employeeid WHERE SUBSTR(signature, 36) = ?", data).Scan(&result)
// if err != nil {
// c.AbortWithError(http.StatusBadRequest, err)
// c.String(http.StatusBadRequest, err.Error())
// return
// }
c.JSON(http.StatusOK, gin.H{
"result": result,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{
"result": count.toString(),
})
}
// c.JSON(http.StatusOK, gin.H{
// "result": result,
// })
// } else {
// c.JSON(http.StatusBadRequest, gin.H{
// "result": count,
// })
// }
}
})
@ -1975,5 +1975,93 @@ func connect() {
}
})
router.POST("/api/update-name", middleware.TokenChecker(), func(c *gin.Context) {
type NewnameData struct {
Data int `json:"data"` //employeeid
Data2 string `json:"data2"` //new name
}
var newnameData NewnameData
if err := c.ShouldBindJSON(&newnameData); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
dbpost, err := db.Prepare("UPDATE employee SET employeename = ? WHERE employeeid = ?")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(newnameData.Data2, newnameData.Data)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Changing Name")
} else {
c.String(http.StatusInternalServerError, "Failed on Changing Name")
}
})
router.POST("/api/update-password", middleware.TokenChecker(), func(c *gin.Context) {
type NewnameData struct {
Data int `json:"data"` //employeeid
Data2 string `json:"data2"` //new password
}
var newnameData NewnameData
if err := c.ShouldBindJSON(&newnameData); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
dbpost, err := db.Prepare("UPDATE esign SET password = ? WHERE employeeid = ?")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(newnameData.Data2, newnameData.Data)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Changing Password")
} else {
c.String(http.StatusInternalServerError, "Failed on Changing Password")
}
})
router.Run(":4320")
}

View file

@ -101,4 +101,4 @@ h1
background-color: color.adjust(#0D64E4, $blackness: 20%)
opacity: 0.6
text-align: center
margin: 1rem 0 0 0
margin: 1rem 0 -0.75rem 0

View file

@ -58,6 +58,8 @@ export default () => {
const [configNewEncPassword, setConfigNewEncPassword] = createSignal('')
const [configError, setConfigError] = createSignal('')
const [configNotification, setConfigNotification] = createSignal(false)
let bldgadditional = false
const getListForApproval = async () => {
@ -322,8 +324,14 @@ export default () => {
const checkCurrentPassword = async () => {
const encCurrentPassword = await securePassword(configPassword())
if (encCurrentPassword === configEncPassword()) {
setConfigError('')
encryptNewPassword()
if (configNewPassword() === '') {
setConfigError('New Password not provided')
setConfigNewEncPassword('')
} else {
setConfigError('')
encryptNewPassword()
}
} else {
setConfigError('Invalid Password')
setConfigNewEncPassword('')
@ -335,7 +343,26 @@ export default () => {
setConfigNewEncPassword(encNewPassword)
}
const saveConfig = () => {}
const saveConfig = async () => {
if (configNewName() !== '') await saveNewName(configNewName())
if (configNewPassword() !== '') await saveNewPassword(configNewEncPassword())
setConfigNotification(true)
}
const saveNewName = async (name: string) => {
await postApi('update-name', {
data: parseInt(ID),
data2: name
})
}
const saveNewPassword = async (password: string) => {
await postApi('update-password', {
data: parseInt(ID),
data2: password
})
}
const logout = async () => {
removeEmployee()
@ -359,7 +386,9 @@ export default () => {
checkCurrentPassword()
}
if (configNewEncPassword() !== '') {
if (configNewPassword() !== '') {
encryptNewPassword()
} else {
encryptNewPassword()
}
})
@ -742,17 +771,40 @@ export default () => {
<Show when={configError() !== ''}>
<span class="required">{configError()}</span>
<Button label='Cancel' edges='curved' design='bo-danger' onClick={() => setOpenConfig(false)} wide />
</Show>
<Show when={configError() === '' && configNewPassword() !== ''}>
<div class='config__button'>
<div class='config__button'>
<Show when={configError() === ''}>
<Button label='Confirm' edges='curved' design='bo-primary' onClick={saveConfig} wide />
<Button label='Cancel' edges='curved' design='bo-danger' onClick={() => setOpenConfig(false)} wide />
</div>
</Show>
</Show>
</div>
</section>
</Padding>
</Modal>
</Modal >
<div onClick={setConfigNotification(false)}>
<Modal trigger={configNotification() === true} background="#123220ff" color="#cdfbe1f0" opacity={0.8}>
<Padding top={1} bottom={1} left={4} right={4}>
<Column>
<Row gap={4}>
<FaSolidThumbsUp size={75} />
<Box curved thickness={3} color="#cdfbe1f0" padding="1rem">
<span class="approval">Approved</span>
</Box>
</Row>
<Row padding="2rem 0 0 0">
<h2>{approvedApplication()}</h2>
</Row>
<Row>
<span class="close-text">Click anywhere to proceed</span>
</Row>
</Column>
</Padding>
</Modal >
</div>
</>
)
}

View file

@ -1,5 +1,5 @@
.name
padding: 1rem 2rem
.profile-name
padding: 1rem 2.25rem
border-radius: 8px
font-size: 1.75rem
font-weight: 800

View file

@ -1,37 +1,43 @@
import './Profile.sass'
import { Logo, Link, Page, Row, Padding, Combobox, Box, Button, Modal, Column, QR, Input, Display } from '../../components'
import { Logo, Link, Page, Row, Padding, Column, Box } from '../../components'
import { IoChevronBack } from 'solid-icons/io'
import { _employeeName, _employeeId } from '../../stores/employee'
export default () => {
return (
<>
<Page>
<Padding left={4.75} right={4.75} top={0} bottom={0}>
<Row content="split">
<Link to="/">
<Row content="left" gap={2}>
<Logo size={200} />
<h1>OCBO e-Sign</h1>
</Row>
</Link>
<Link to="/">
<Row content="right">
<IoChevronBack size={45} />
<span class="back-button-text">Back</span>
</Row>
</Link>
</Row>
<Column>
<h1 class="name">{sessionStorage.getItem('name')}</h1>
<Row content="left">
<span>Role:</span>
export default () => (
<>
<Page>
<Padding left={4.75} right={4.75} top={0} bottom={0}>
<Row content="split">
<Link to="/">
<Row content="left" gap={2}>
<Logo size={200} />
<h1>OCBO e-Sign</h1>
</Row>
</Column>
</Padding>
</Page>
</>
)
}
</Link>
<Link to="/">
<Row content="right">
<IoChevronBack size={45} />
<span class="back-button-text">Back</span>
</Row>
</Link>
</Row>
<Column>
<h1 class="profile-name">{sessionStorage.getItem('name')}</h1>
<Padding top={2} left={0} right={0} bottom={0}>
<Row content='left'>
<Box curved thickness={2} padding="2.25rem" color="#253849be" background="#04040660" width='500px'>
<Column> Username:
<span>Username:</span>
</Column>
</Box>
</Row>
</Padding>
</Column>
</Padding>
</Page>
</>
)

View file

@ -6,4 +6,4 @@ export { default as getApiMulti } from './getApiMulti.ts';
export { default as postApi } from './postApi.ts';
export { default as statusPopsApi } from './statusPopsApi.ts';
export { default as voidPopsApi } from './voidPopsApi.ts';
export { default as securePassword } from './securePassword.ts';