mirror of
https://github.com/adanrsantos/ThePlaceHolders.git
synced 2024-12-16 12:20:37 -06:00
Compare commits
8 commits
3462fc966c
...
ab5c4342c8
Author | SHA1 | Date | |
---|---|---|---|
ab5c4342c8 | |||
2bc52182f7 | |||
502a87ef24 | |||
09602d48f1 | |||
5e85dfc9da | |||
ac664eddf3 | |||
Logan Gatlin | f3de96ac54 | ||
d25e5c7d1a |
42
email.go
Normal file
42
email.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"gopkg.in/gomail.v2"
|
||||||
|
"net/smtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Send(body string) {
|
||||||
|
from := "xterminate18181@gmail.com"
|
||||||
|
pass := "nvzp fodm ihzw gter"
|
||||||
|
to := "joson.anthoney@frontdomain.org"
|
||||||
|
|
||||||
|
msg := "From: " + from + "\n" +
|
||||||
|
"To: " + to + "\n" +
|
||||||
|
"Subject: Hello there\n\n" +
|
||||||
|
body
|
||||||
|
|
||||||
|
err := smtp.SendMail("smtp.gmail.com:587",
|
||||||
|
smtp.PlainAuth("", from, pass, "smtp.gmail.com"),
|
||||||
|
from, []string{to}, []byte(msg))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("smtp error: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Successfully sended to " + to)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MailTest() {
|
||||||
|
d := gomail.NewDialer("smtp.gmail.com", 587, "xterminate18181@gmail.com", "nvzp fodm ihzw gter")
|
||||||
|
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
|
m := gomail.NewMessage()
|
||||||
|
m.SetHeader("From", "xterminate18181@gmail.com")
|
||||||
|
m.SetHeader("To", "logan@gatlintc.com")
|
||||||
|
m.SetHeader("Subject", "Confirm Email")
|
||||||
|
m.SetBody("text/html", "Test body")
|
||||||
|
if err := d.DialAndSend(m); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
6
go.mod
6
go.mod
|
@ -7,4 +7,8 @@ require (
|
||||||
golang.org/x/crypto v0.27.0
|
golang.org/x/crypto v0.27.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/gorilla/securecookie v1.1.2 // indirect
|
require (
|
||||||
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||||
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -6,3 +6,7 @@ github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzq
|
||||||
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
|
|
|
@ -20,6 +20,7 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
Send("test body")
|
||||||
// Grab command line arguments
|
// Grab command line arguments
|
||||||
ipFlag := flag.String("ip", "127.0.0.1", "IP address to receive traffic from")
|
ipFlag := flag.String("ip", "127.0.0.1", "IP address to receive traffic from")
|
||||||
portFlag := flag.String("port", "8080", "Port to receive traffic from")
|
portFlag := flag.String("port", "8080", "Port to receive traffic from")
|
||||||
|
|
132
static/canvas.js
132
static/canvas.js
|
@ -3,9 +3,39 @@ const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
const canvasSize = 500;
|
const canvasSize = 500;
|
||||||
const dataSize = 1000;
|
const dataSize = 1000;
|
||||||
|
const gridCount = 10 ;
|
||||||
canvas.width = canvasSize;
|
canvas.width = canvasSize;
|
||||||
canvas.height = canvasSize;
|
canvas.height = canvasSize;
|
||||||
|
|
||||||
|
//let pixelSize = canvasSize / dataSize;
|
||||||
|
let pixelSize = canvasSize / gridCount;
|
||||||
|
const centerPixel = pixelSize / 2;
|
||||||
|
|
||||||
|
function drawGrid() {
|
||||||
|
ctx.strokeStyle = '#000'; // Set grid line color
|
||||||
|
ctx.lineWidth = 1; // Set grid line width
|
||||||
|
|
||||||
|
// Draw horizontal lines
|
||||||
|
for (let i = 0; i <= gridCount; i++) {
|
||||||
|
let y = i * pixelSize;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, y); // Start the line at the left edge (x = 0)
|
||||||
|
ctx.lineTo(canvasSize, y); // Draw to the right edge (x = canvasSize)
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw vertical lines
|
||||||
|
for (let i = 0; i <= gridCount; i++) {
|
||||||
|
let x = i * pixelSize;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, 0); // Start the line at the top edge (y = 0)
|
||||||
|
ctx.lineTo(x, canvasSize); // Draw to the bottom edge (y = canvasSize)
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawGrid();
|
||||||
|
|
||||||
class Point {
|
class Point {
|
||||||
// new Point(x, y)
|
// new Point(x, y)
|
||||||
constructor(x, y) {
|
constructor(x, y) {
|
||||||
|
@ -15,15 +45,15 @@ class Point {
|
||||||
// Convert canvas position to data position
|
// Convert canvas position to data position
|
||||||
canvasToData() {
|
canvasToData() {
|
||||||
return new Point(
|
return new Point(
|
||||||
Math.round(this.x / canvasSize * dataSize),
|
Math.round(this.x / canvasSize * gridCount),
|
||||||
Math.round(this.y / canvasSize * dataSize)
|
Math.round(this.y / canvasSize * gridCount)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Convert data position to canvas position
|
// Convert data position to canvas position
|
||||||
dataToCanvas() {
|
dataToCanvas() {
|
||||||
return new Point(
|
return new Point(
|
||||||
this.x / dataSize * canvasSize,
|
this.x / gridCount * canvasSize,
|
||||||
this.y / dataSize * canvasSize
|
this.y / gridCount * canvasSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Convert to array index
|
// Convert to array index
|
||||||
|
@ -51,98 +81,14 @@ class Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pixelSize = canvasSize / dataSize;
|
function draw(point) {
|
||||||
const centerPixel = pixelSize / 2;
|
point = point.canvasToData().dataToCanvas()
|
||||||
|
ctx.fillRect(point.x, point.y, pixelSize, pixelSize);
|
||||||
function draw(x, y) {
|
|
||||||
ctx.fillRect(x, y, pixelSize, pixelSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.addEventListener("mousedown", (e) => {
|
canvas.addEventListener("mousedown", (e) => {
|
||||||
let x = e.clientX - canvas.getBoundingClientRect().left - centerPixel;
|
let x = e.clientX - canvas.getBoundingClientRect().left - centerPixel;
|
||||||
let y = e.clientY - canvas.getBoundingClientRect().top - centerPixel;
|
let y = e.clientY - canvas.getBoundingClientRect().top - centerPixel;
|
||||||
draw(x, y);
|
let point = new Point(x, y)
|
||||||
})
|
draw(point);
|
||||||
|
|
||||||
//const toolbar = document.getElementById("toolbar");
|
|
||||||
//const strokePicker = document.getElementById("stroke");
|
|
||||||
//const canvasOffsetX = canvas.offsetLeft;
|
|
||||||
//const canvasOffsetY = canvas.offsetTop;
|
|
||||||
//canvas.width = 150;
|
|
||||||
//canvas.height = 150;
|
|
||||||
|
|
||||||
/*
|
|
||||||
let isPainting = false;
|
|
||||||
let lineWidth = 5;
|
|
||||||
let strokeColor = "#000000";
|
|
||||||
let startX;
|
|
||||||
let startY;
|
|
||||||
|
|
||||||
function drawGrid(lineInterval, lineColor) {
|
|
||||||
// Set the color of the grid lines
|
|
||||||
ctx.strokeStyle = lineColor;
|
|
||||||
ctx.lineWidth = 1; // Set the gridline thickness
|
|
||||||
|
|
||||||
// Draw vertical grid lines
|
|
||||||
for (let x = 0; x <= canvas.width; x += lineInterval) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x, 0); // Start from top of the canvas
|
|
||||||
ctx.lineTo(x, canvas.height); // Draw line down to the bottom
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw horizontal grid lines
|
|
||||||
for (let y = 0; y <= canvas.height; y += lineInterval) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0, y); // Start from the left of the canvas
|
|
||||||
ctx.lineTo(canvas.width, y); // Draw line across to the right
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
ctx.beginPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the drawGrid function with 50px intervals and a light gray color
|
|
||||||
drawGrid(10, '#A9A9A9');
|
|
||||||
|
|
||||||
toolbar.addEventListener("click", e => {
|
|
||||||
if (e.target.id === "clear"){
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
drawGrid(10, '#A9A9A9');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.target.id === "lineWidth"){
|
|
||||||
lineWidth = e.target.value;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
strokePicker.addEventListener("input", (e) => {
|
|
||||||
strokeColor = e.target.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
const draw = (e) => {
|
|
||||||
if (!isPainting){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ctx.lineWidth = lineWidth;
|
|
||||||
ctx.strokeStyle = strokeColor;
|
|
||||||
ctx.lineCap = "round";
|
|
||||||
|
|
||||||
ctx.lineTo(e.clientX - canvasOffsetX, e.clientY - canvasOffsetY);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.addEventListener("mousedown", (e) => {
|
|
||||||
isPainting = true;
|
|
||||||
startX = e.clientX;
|
|
||||||
startY = e.clientY;
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.addEventListener("mouseup", (e) => {
|
|
||||||
isPainting = false;
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.beginPath();
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.addEventListener("mousemove", draw);
|
|
||||||
*/
|
|
||||||
|
|
|
@ -2,4 +2,14 @@ input[type=number]::-webkit-inner-spin-button,
|
||||||
input[type=number]::-webkit-outer-spin-button {
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
lol
|
||||||
|
|
||||||
|
*/
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="bg-warning">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
@ -7,16 +7,25 @@
|
||||||
<title>UTSA Placeholders</title>
|
<title>UTSA Placeholders</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||||
<link href="./confirmation.css" rel="stylesheet">
|
<link href="./confirmation.css" type="text/css "rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form>
|
<form class="mt-5 bg-warning">
|
||||||
<div class="mb-3">
|
<div class="m-3 fs-4 d-block bg-transparent text-center">
|
||||||
Check your email for a 6 digit code and enter it below.
|
Check your email for a 6-digit code and enter it below.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="input-group input-group-lg d-flex justify-content-center">
|
||||||
<input for="">
|
<input class="input-group-text font-monospace" for="" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="m-3 d-block text-center">
|
||||||
|
<input id="submit" type="submit" value="Confirm" class="btn btn-secondary">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5 fs-6 text-center">
|
||||||
|
<!--add link below to href or something to send another email to the registered user-->
|
||||||
|
<a href="">Send again.</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
:root {
|
||||||
|
--utsa-orange: #f15a22;
|
||||||
|
--utsa-blue: #0c2340;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-color: var(--utsa-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
#rform {
|
||||||
|
border-radius: 10px;
|
||||||
|
border: solid var(--utsa-orange) 2px;
|
||||||
|
margin: 100px;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formbg {
|
||||||
|
background-color: var(--utsa-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
#h3bg {
|
||||||
|
background-color: var(--utsa-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 10px;
|
||||||
|
background-color: var(--utsa-blue);
|
||||||
|
color: var(--utsa-orange);
|
||||||
|
font-size: 40px;
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-text {
|
||||||
|
padding: 3px;
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
}
|
|
@ -10,6 +10,26 @@
|
||||||
<link href="./forgotpassword.css" rel="stylesheet">
|
<link href="./forgotpassword.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id="h3bg" class="d-flex justify-content-center"><h3 id="r">UTSA Place</h3></div>
|
||||||
|
<div id="formbg" class="d-flex p-2 justify-content-center align-items-center">
|
||||||
|
<form id="rform" method="post">
|
||||||
|
<div class="d-flex justify-content-center fs-3">
|
||||||
|
Forgot Password
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email address</label>
|
||||||
|
<input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp" required>
|
||||||
|
<div id="emailHelp" class="form-text">Enter your email and we will send you a 6-digit recovery code.</div>
|
||||||
|
</div>
|
||||||
|
<input id="submit" type="submit" class="btn btn-primary" value="Send Code">
|
||||||
|
<br>
|
||||||
|
<div class="d-flex mt-2">
|
||||||
|
<small>
|
||||||
|
Click <a href="login.html">here</a> to go back to login.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -20,6 +20,12 @@
|
||||||
<li>
|
<li>
|
||||||
<a href="./login.html"> Login </a>
|
<a href="./login.html"> Login </a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="./forgotpassword.html"> Forgot Password </a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="./confirmation.html"> Confirmation </a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="./logout"> Log Out </a>
|
<a href="./logout"> Log Out </a>
|
||||||
</li>
|
</li>
|
||||||
|
|
22
users.go
22
users.go
|
@ -14,6 +14,7 @@ const SESSION_COOKIE_NAME = "utsa-place-session"
|
||||||
const SESSION_AUTH = "auth"
|
const SESSION_AUTH = "auth"
|
||||||
const SESSION_STARTED = "age"
|
const SESSION_STARTED = "age"
|
||||||
const SESSION_CONFIRMED = "confirmed"
|
const SESSION_CONFIRMED = "confirmed"
|
||||||
|
const SESSION_CONFIRM_KEY = "confirm-key"
|
||||||
|
|
||||||
const ENCRYPTION_STRENGTH = 14
|
const ENCRYPTION_STRENGTH = 14
|
||||||
|
|
||||||
|
@ -139,15 +140,20 @@ func (s *Server) handle_register(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handle_confirmation(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handle_confirmation(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := s.Sessions.Get(r, SESSION_COOKIE_NAME)
|
switch r.Method {
|
||||||
if err != nil {
|
case http.MethodGet:
|
||||||
s.handle_logout(w, r)
|
session, err := s.Sessions.Get(r, SESSION_COOKIE_NAME)
|
||||||
http.Redirect(w, r, "/register", http.StatusFound)
|
if err != nil {
|
||||||
return
|
s.handle_logout(w, r)
|
||||||
|
http.Redirect(w, r, "/register", http.StatusFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
confirmed := session.Values[SESSION_CONFIRMED]
|
||||||
|
fmt.Println("Session confirmed: ", confirmed)
|
||||||
|
http.ServeFile(w, r, "./static/confirmation.html")
|
||||||
|
case http.MethodPost:
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
confirmed := session.Values[SESSION_CONFIRMED]
|
|
||||||
fmt.Println("Session confirmed: ", confirmed)
|
|
||||||
http.ServeFile(w, r, "./static/confirmation.html")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) secret(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) secret(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue