charts
This commit is contained in:
parent
65eddf6fd8
commit
39862c0516
525
main.go
525
main.go
@ -2,18 +2,22 @@ package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v5"
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/apis"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
)
|
||||
@ -29,80 +33,99 @@ type EmailConfigurationResponse struct {
|
||||
} `json:"items"`
|
||||
}
|
||||
|
||||
type GenericData struct {
|
||||
XMLName xml.Name `xml:"GenericData"`
|
||||
DataSet []Obs `xml:"DataSet>Obs"`
|
||||
}
|
||||
|
||||
type Obs struct {
|
||||
ObsKey []ObsKey `xml:"ObsKey>Value"` // Dynamic key-value pairs
|
||||
ObsValue ObsValue `xml:"ObsValue"`
|
||||
}
|
||||
|
||||
type ObsKey struct {
|
||||
ID string `xml:"id,attr"` // Attribute for 'id'
|
||||
Value string `xml:"value,attr"` // Attribute for 'value'
|
||||
}
|
||||
|
||||
type ObsValue struct {
|
||||
Value string `xml:"value,attr"` // Attribute for 'value'
|
||||
}
|
||||
|
||||
// Helper function to map ObsKey into a dictionary
|
||||
func mapObsKey(keys []ObsKey) map[string]string {
|
||||
result := map[string]string{}
|
||||
for _, key := range keys {
|
||||
result[key.ID] = key.Value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Helper function to clean XML namespace prefixes
|
||||
func removeNamespace(xmlBytes []byte) string {
|
||||
return strings.ReplaceAll(string(xmlBytes), "generic:", "")
|
||||
}
|
||||
|
||||
// Function to fetch XML from an API and convert it to JSON
|
||||
func fetchAndConvertXMLToJSON(apiURL string) ([]map[string]interface{}, error) {
|
||||
// Call the API and get the XML response
|
||||
resp, err := http.Get(apiURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read the response body
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Clean the XML by removing namespace prefixes
|
||||
cleanXML := []byte(removeNamespace(body))
|
||||
|
||||
// Parse the cleaned XML data
|
||||
var data GenericData
|
||||
err = xml.Unmarshal(cleanXML, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Transform the data for JSON output
|
||||
response := []map[string]interface{}{}
|
||||
for _, obs := range data.DataSet {
|
||||
obsMap := map[string]interface{}{
|
||||
"ObsKey": mapObsKey(obs.ObsKey),
|
||||
"ObsValue": obs.ObsValue,
|
||||
}
|
||||
response = append(response, obsMap)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
var app *pocketbase.PocketBase
|
||||
|
||||
func main() {
|
||||
// app := pocketbase.New()
|
||||
app = pocketbase.New()
|
||||
|
||||
//send mail while status changed from app admin
|
||||
app.OnRecordBeforeUpdateRequest().Add(func(e *core.RecordUpdateEvent) error {
|
||||
if e.Collection.Name == "users" {
|
||||
// Fetch the original record by ID
|
||||
originalRecord, err := app.Dao().FindRecordById("users", e.Record.GetString("id"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch original record: %v", err)
|
||||
}
|
||||
|
||||
// Get the old status before the update
|
||||
oldStatus := originalRecord.GetString("status")
|
||||
newStatus := e.Record.GetString("status")
|
||||
|
||||
// If the status has changed, send an email
|
||||
if newStatus != oldStatus {
|
||||
userEmail := e.Record.GetString("email")
|
||||
userName := e.Record.GetString("username")
|
||||
if userEmail != "" {
|
||||
|
||||
var subject string
|
||||
var body string
|
||||
|
||||
// Define the email content based on status
|
||||
if newStatus == "Approved" {
|
||||
subject = "Registration Approved – FCSC"
|
||||
body = fmt.Sprintf(`
|
||||
<p>Dear %s,</p>
|
||||
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
||||
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
||||
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
||||
`, userName)
|
||||
} else if newStatus == "Denied" {
|
||||
subject = "Registration Update – FCSC"
|
||||
body = fmt.Sprintf(`
|
||||
<p>Dear %s,</p>
|
||||
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
||||
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
||||
<p>We appreciate your understanding and thank you for your interest.</p>
|
||||
<p>Best regards,</p>
|
||||
`, userName)
|
||||
} else {
|
||||
// If the status is neither "Approved" nor "Denied", skip sending an email
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create the email message
|
||||
message := &mailer.Message{
|
||||
From: mail.Address{
|
||||
Name: "FCSC",
|
||||
Address: app.Settings().Meta.SenderAddress, // Replace with your sender's email
|
||||
},
|
||||
To: []mail.Address{
|
||||
{
|
||||
Name: userName,
|
||||
Address: userEmail,
|
||||
},
|
||||
},
|
||||
Subject: subject,
|
||||
HTML: body,
|
||||
}
|
||||
|
||||
// Send the email
|
||||
err = app.NewMailClient().Send(message)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send status change email: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Status change email sent successfully to:", userEmail)
|
||||
// Check if the status has changed
|
||||
if oldStatus != newStatus {
|
||||
err := sendStatusChangeEmail(app, e.Record, newStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,7 +192,7 @@ func main() {
|
||||
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||
|
||||
e.Router.GET("/api/custom/approve", func(c echo.Context) error {
|
||||
userId := c.QueryParam("userId") // Get userId from query parameters
|
||||
userId := c.QueryParam("userId")
|
||||
if userId == "" {
|
||||
return c.JSON(400, map[string]interface{}{
|
||||
"code": 400,
|
||||
@ -177,7 +200,7 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
// Find the user record in PocketBase by userId
|
||||
// Find the user record
|
||||
record, err := app.Dao().FindRecordById("users", userId)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
@ -186,8 +209,60 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
// Set the verified status to true
|
||||
// Check if the email is already verified
|
||||
if record.GetBool("reviewed") {
|
||||
return c.HTML(http.StatusOK, `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.message-container {
|
||||
text-align: center;
|
||||
background-color: #ffe0e0;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.message-container h1 {
|
||||
font-size: 24px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.message-container p {
|
||||
font-size: 16px;
|
||||
color: #880e4f;
|
||||
}
|
||||
.icon {
|
||||
font-size: 50px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-container">
|
||||
<div class="icon">✖</div>
|
||||
<h1>Your Already Reviewed</h1>
|
||||
<p>You have already been reviewed. No further action is required.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
// Update the status
|
||||
newStatus := "Approved"
|
||||
record.Set("verified", true)
|
||||
record.Set("status", newStatus)
|
||||
record.Set("reviewed", true)
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"code": 500,
|
||||
@ -195,39 +270,8 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
// Prepare the email details
|
||||
name := record.GetString("username")
|
||||
email := record.GetString("email")
|
||||
subject := "Registration Approved – FCSC"
|
||||
body := fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
<p>Dear %s,</p>
|
||||
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
||||
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
||||
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
||||
</body>
|
||||
</html>
|
||||
`, name)
|
||||
|
||||
// Create the email message
|
||||
message := &mailer.Message{
|
||||
From: mail.Address{
|
||||
Name: "FCSC",
|
||||
Address: app.Settings().Meta.SenderAddress,
|
||||
},
|
||||
To: []mail.Address{
|
||||
{
|
||||
Name: name,
|
||||
Address: email,
|
||||
},
|
||||
},
|
||||
Subject: subject,
|
||||
HTML: body,
|
||||
}
|
||||
|
||||
// Send the approval email
|
||||
err = app.NewMailClient().Send(message)
|
||||
// Send the status change email
|
||||
err = sendStatusChangeEmail(app, record, newStatus)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"code": 500,
|
||||
@ -235,9 +279,8 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
// Render a success message as an HTML response
|
||||
return c.HTML(http.StatusOK, `
|
||||
<html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
@ -290,7 +333,7 @@ func main() {
|
||||
|
||||
// Approve Endpoint
|
||||
e.Router.GET("/api/custom/reject", func(c echo.Context) error {
|
||||
userId := c.QueryParam("userId") // Get userId from query parameters
|
||||
userId := c.QueryParam("userId")
|
||||
if userId == "" {
|
||||
return c.JSON(400, map[string]interface{}{
|
||||
"code": 400,
|
||||
@ -307,49 +350,77 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
// Set the verified status to false
|
||||
record.Set("verified", false)
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"code": 500,
|
||||
"message": "Failed to update user status.",
|
||||
// Check if the email is already verified
|
||||
if record.GetBool("reviewed") {
|
||||
return c.HTML(http.StatusOK, `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.message-container {
|
||||
text-align: center;
|
||||
background-color: #ffe0e0;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.message-container h1 {
|
||||
font-size: 24px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.message-container p {
|
||||
font-size: 16px;
|
||||
color: #880e4f;
|
||||
}
|
||||
.icon {
|
||||
font-size: 50px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-container">
|
||||
<div class="icon">✖</div>
|
||||
<h1>Your Already Reviewed</h1>
|
||||
<p>You have already been reviewed. No further action is required.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
// Check if the status is already "Denied" to avoid duplicate email
|
||||
if record.GetString("status") == "Denied" {
|
||||
return c.JSON(400, map[string]interface{}{
|
||||
"code": 400,
|
||||
"message": "User is already rejected.",
|
||||
})
|
||||
}
|
||||
|
||||
// Prepare the rejection email details
|
||||
name := record.GetString("username")
|
||||
email := record.GetString("email")
|
||||
subject := "Registration Update – FCSC"
|
||||
body := fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
<p>Dear %s,</p>
|
||||
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
||||
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
||||
<p>We appreciate your understanding and thank you for your interest.</p>
|
||||
<p>Best regards,</p>
|
||||
</body>
|
||||
</html>
|
||||
`, name)
|
||||
|
||||
// Create the rejection email message
|
||||
message := &mailer.Message{
|
||||
From: mail.Address{
|
||||
Name: "FCSC",
|
||||
Address: app.Settings().Meta.SenderAddress,
|
||||
},
|
||||
To: []mail.Address{
|
||||
{
|
||||
Name: name,
|
||||
Address: email,
|
||||
},
|
||||
},
|
||||
Subject: subject,
|
||||
HTML: body,
|
||||
// Update the status
|
||||
newStatus := "Denied"
|
||||
record.Set("verified", true)
|
||||
record.Set("status", newStatus)
|
||||
record.Set("reviewed", true)
|
||||
if err := app.Dao().SaveRecord(record); err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"code": 500,
|
||||
"message": "Failed to verify user.",
|
||||
})
|
||||
}
|
||||
|
||||
// Send the rejection email
|
||||
err = app.NewMailClient().Send(message)
|
||||
// Send the status change email
|
||||
err = sendStatusChangeEmail(app, record, newStatus)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"code": 500,
|
||||
@ -359,44 +430,44 @@ func main() {
|
||||
|
||||
// Render a success message as an HTML response
|
||||
return c.HTML(http.StatusOK, `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>User Rejected</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #ffe6e6; /* Light red background */
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.message-box {
|
||||
text-align: center;
|
||||
color: #d9534f; /* Bootstrap red */
|
||||
}
|
||||
.message-box i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.message-box p {
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-box">
|
||||
<i>❌</i>
|
||||
<h1>User Rejected</h1>
|
||||
<p>Rejection email sent successfully.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>User Rejected</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #ffe6e6;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.message-box {
|
||||
text-align: center;
|
||||
color: #d9534f;
|
||||
}
|
||||
.message-box i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.message-box p {
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-box">
|
||||
<i>❌</i>
|
||||
<h1>User Rejected</h1>
|
||||
<p>Rejection email sent successfully.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
})
|
||||
|
||||
@ -410,6 +481,7 @@ func main() {
|
||||
return nil
|
||||
})
|
||||
|
||||
//Feedback Mail Trigger
|
||||
app.OnRecordAfterCreateRequest().Add(func(e *core.RecordCreateEvent) error {
|
||||
if e.Record.Collection().Name == "feedback" {
|
||||
// Retrieve feedback details
|
||||
@ -635,6 +707,55 @@ func verifyEmailHandler(c echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
// Check if the email is already verified
|
||||
if record.GetBool("user_mail_verify") {
|
||||
return c.HTML(http.StatusOK, `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.message-container {
|
||||
text-align: center;
|
||||
background-color: #ffe0e0;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.message-container h1 {
|
||||
font-size: 24px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.message-container p {
|
||||
font-size: 16px;
|
||||
color: #880e4f;
|
||||
}
|
||||
.icon {
|
||||
font-size: 50px;
|
||||
color: #b71c1c;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-container">
|
||||
<div class="icon">✖</div>
|
||||
<h1>Email Already Verified</h1>
|
||||
<p>Your email has already been verified. No further action is required.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
// Set the verified status to true
|
||||
record.Set("user_mail_verify", true)
|
||||
// log.Printf("Failed to verify user: %v", err)
|
||||
@ -710,6 +831,7 @@ func verifyEmailHandler(c echo.Context) error {
|
||||
func sendAdminEmail(app *pocketbase.PocketBase, userID, username, userEmail string) error {
|
||||
adminName := "Admin"
|
||||
subject := "New User Registration Pending Review"
|
||||
|
||||
body := fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
@ -755,3 +877,60 @@ func sendAdminEmail(app *pocketbase.PocketBase, userID, username, userEmail stri
|
||||
log.Println("Admin email sent successfully.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func sendStatusChangeEmail(app *pocketbase.PocketBase, record *models.Record, newStatus string) error {
|
||||
userEmail := record.GetString("email")
|
||||
userName := record.GetString("username")
|
||||
|
||||
if userEmail == "" {
|
||||
return fmt.Errorf("user email is empty")
|
||||
}
|
||||
|
||||
var subject, body string
|
||||
|
||||
if newStatus == "Approved" {
|
||||
subject = "Registration Approved – FCSC"
|
||||
body = fmt.Sprintf(`
|
||||
<p>Dear %s,</p>
|
||||
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
||||
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
||||
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
||||
`, userName)
|
||||
} else if newStatus == "Denied" {
|
||||
subject = "Registration Update – FCSC"
|
||||
body = fmt.Sprintf(`
|
||||
<p>Dear %s,</p>
|
||||
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
||||
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
||||
<p>We appreciate your understanding and thank you for your interest.</p>
|
||||
<p>Best regards,</p>
|
||||
`, userName)
|
||||
} else {
|
||||
// If the status is neither "Approved" nor "Denied", skip sending an email
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create and send the email
|
||||
message := &mailer.Message{
|
||||
From: mail.Address{
|
||||
Name: "FCSC",
|
||||
Address: app.Settings().Meta.SenderAddress,
|
||||
},
|
||||
To: []mail.Address{
|
||||
{
|
||||
Name: userName,
|
||||
Address: userEmail,
|
||||
},
|
||||
},
|
||||
Subject: subject,
|
||||
HTML: body,
|
||||
}
|
||||
|
||||
err := app.NewMailClient().Send(message)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send email: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Status change email sent successfully to: %s", userEmail)
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user