adding masked email
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Conner McCall 2024-01-26 09:12:33 -06:00
parent b716c6397e
commit 67748b058b
17 changed files with 265 additions and 6 deletions

View file

@ -1,12 +1,14 @@
FROM golang:1.17 FROM golang:1.18
WORKDIR /go/src/app WORKDIR /go/src/app
COPY src build-src COPY go.mod go.sum ./
RUN go mod init connermccall.me RUN go mod download && go mod verify
RUN go get -u github.com/gin-gonic/gin
RUN go build build-src/main.go
COPY src build-src
RUN go build build-src/*.go
COPY static static
RUN rm -rf src RUN rm -rf src
EXPOSE 8080/tcp EXPOSE 8080/tcp

2
go.mod
View file

@ -3,6 +3,7 @@ module connermccall.me
go 1.17 go 1.17
require ( require (
github.com/dvcrn/maskedemail-cli v0.0.0-20230603113757-7a0ce82189f6 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.7.7 // indirect github.com/gin-gonic/gin v1.7.7 // indirect
github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/locales v0.13.0 // indirect
@ -12,6 +13,7 @@ require (
github.com/json-iterator/go v1.1.9 // indirect github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect github.com/ugorji/go/codec v1.1.7 // indirect

4
go.sum
View file

@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dvcrn/maskedemail-cli v0.0.0-20230603113757-7a0ce82189f6 h1:ORgd6cYAg5GdPNNE95vFXyy73rx8xy1XCprpVDGN1jE=
github.com/dvcrn/maskedemail-cli v0.0.0-20230603113757-7a0ce82189f6/go.mod h1:TU8E0RslsOUiXYsICzcpPcThV56wOhuGt+5+NNXDx6k=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
@ -20,6 +22,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=

View file

@ -2,10 +2,12 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
"encoding/json"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -60,5 +62,33 @@ func main() {
"message": "OK", "message": "OK",
}) })
}) })
router.Static("/maskedemail", "./static/maskedemail")
router.GET("mask", func(c *gin.Context) {
description := c.Query("description")
if description == "" {
// Return an error response if description is not provided
c.JSON(http.StatusBadRequest, gin.H{"error": "Description is required"})
return
}
htmlx := c.Query("htmlx")
domain := c.Query("domain") // This will be an empty string if not provided
email, err := CreateMaskedEmail(description, domain)
if err != nil {
// Log the error and return an error response
log.Println("Error:", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create masked email"})
return
}
log.Print(email)
if htmlx != "true" {
c.String(http.StatusOK, email)
} else {
res := fmt.Sprintf("<h1>%s</h1>", email)
c.String(http.StatusOK, res)
}
})
router.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") router.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
} }

29
src/maskedmail.go Normal file
View file

@ -0,0 +1,29 @@
package main
import (
"log"
"os"
"github.com/dvcrn/maskedemail-cli/pkg"
)
func CreateMaskedEmail(alias string, domain string) (string, error) {
var fastmailAPIKey, fastmailAccountId string
fastmailAPIKey = os.Getenv("FASTMAIL_API_KEY")
fastmailAccountId = os.Getenv("FASTMAIL_ACCOUNT_ID")
// Prepare the request payload
client := pkg.NewClient(fastmailAPIKey, "personal-api", "3654417c")
session, err := client.Session()
if err != nil {
log.Fatalf("initializing session: %v", err)
}
createRes, err := client.CreateMaskedEmail(session, fastmailAccountId, "", alias, "", true)
if err != nil {
log.Fatalf("error creating masked email: %v", err)
}
return createRes.Email, nil
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,139 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="lib/htmx.min.js"></script>
<title>Create Masked Email</title>
<meta name="viewport"
content="width=device-width,initial-scale=1" />
<link rel="manifest"
href="manifest.json" />
<link id="favicon"
rel="shortcut icon"
sizes="32x32"
href="icon-32x32.png">
<style>
:root {
--color: #1a40bc;
--input-width: 70vw;
}
.main {
min-height: 70vh;
align-items: center;
display: flex;
justify-content: center;
flex-direction: column;
gap: 1rem;
}
h1,
input::-webkit-input-placeholder,
button {
font-family: 'roboto', sans-serif;
transition: all 0.3s ease-in-out;
}
h1 {
padding: 0 1rem;
}
form {
box-sizing: border-box;
box-shadow: 2px 2px 5px 1px rgba(0, 0, 0, 0.2);
padding-bottom: 2rem;
padding-top:2rem;
border-radius: 3px;
}
input {
margin: 40px 25px;
width: var(--input-width);
display: block;
border: none;
padding: 10px 0;
border-bottom: solid 1px var(--color);
transition: all 0.3s cubic-bezier(.64, .09, .08, 1);
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 96%, var(--color) 4%);
background-position: -var(--input-width) 0;
background-size: var(--input-width) 100%;
background-repeat: no-repeat;
color: darken(var(--color), 20%);
&:focus,
&:valid {
box-shadow: none;
outline: none;
background-position: 0 0;
&::-webkit-input-placeholder {
color: var(--color);
font-size: 11px;
transform: translateY(-20px);
visibility: visible !important;
}
}
}
button {
border: none;
font-size: 1.4rem;
background: var(--color);
cursor: pointer;
border-radius: 3px;
padding: 6px;
width: var(--input-width);
color: white;
margin-left: 25px;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.2);
&:hover {
transform: translateY(-3px);
box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.2);
}
}
.reset {
font-size: 1.1rem;
color: -var(--color);
display: block;
margin-top:.5rem;
}
.htmx-indicator{
margin: 1rem auto 0;
text-align: center;
display:block;
}
.htmx-request .htmx-indicator{
display:block;
}
.htmx-request.htmx-indicator{
display:block;
}
</style>
</head>
<body>
<div class="main">
<form id="mask-form"
hx-get="/mask"
hx-swap="innerHTML">
<input type="text"
name="description"
required
minlength="2">
<input type="text"
name="domain">
<input type="hidden"
name="htmlx"
value="true">
<button type="submit">
Generate Email
</button>
<div class="htmx-indicator">Loading...</div>
</form>
<div>
<a class="reset" href="/maskedemail">Reset</a>
</div>
</div>
</body>
</html>

1
static/maskedemail/lib/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,52 @@
{
"name": "Masked Email Generator",
"short_name": "masked",
"theme_color": "#1a40bc",
"background_color": "#fff",
"display": "standalone",
"orientation": "portrait",
"scope": "/",
"start_url": "/maskedemail",
"icons": [
{
"src": "./images/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "./images/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "./images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "./images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "./images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "./images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./images/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "./images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}