email accepted users
parent
cee8b75bad
commit
c43adc49fb
|
@ -1,8 +1,67 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// TODO function for reading smtp.pw from /town/docs
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
func sendInviteEmail() error {
|
"git.tilde.town/tildetown/town/email"
|
||||||
// TODO
|
"git.tilde.town/tildetown/town/invites"
|
||||||
return nil
|
)
|
||||||
|
|
||||||
|
const emailText = `hello!
|
||||||
|
|
||||||
|
You applied to https://tilde.town at some point and your application has been approved ^_^
|
||||||
|
|
||||||
|
Your invite code is: %s
|
||||||
|
|
||||||
|
To redeem your code, please open a terminal and run:
|
||||||
|
|
||||||
|
ssh welcome@tilde.town
|
||||||
|
|
||||||
|
You'll fill in details like your desired username and SSH public key.
|
||||||
|
|
||||||
|
If you're brand new to SSH or have never heard of it that is okay!
|
||||||
|
|
||||||
|
This page has information on what SSH is and how to use it, including how to create an ssh key pair which you'll need to access your town account: https://tilde.town/wiki/getting-started/ssh.html
|
||||||
|
|
||||||
|
If you run into confusion or problems creating a key pair on your computer, this page can generate one for you: https://tilde.town/keymachine . However you'll still need to save the generated key files to your computer in order to use them.
|
||||||
|
|
||||||
|
If you end up stuck, e-mail root@tilde.town with any questions.
|
||||||
|
|
||||||
|
See you on the server,
|
||||||
|
~vilmibm`
|
||||||
|
|
||||||
|
func loadPassword() (string, error) {
|
||||||
|
f, err := os.Open("/town/docs/smtp.pw")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
pw := make([]byte, 100)
|
||||||
|
|
||||||
|
n, err := f.Read(pw)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return "", errors.New("read nothing")
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(pw[0:n]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendInviteEmail(invite invites.Invite) error {
|
||||||
|
pw, err := loadPassword()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not read password: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := fmt.Sprintf(emailText, invite.Code)
|
||||||
|
|
||||||
|
mailer := email.NewExternalMailer(pw)
|
||||||
|
return mailer.Send(
|
||||||
|
invite.Email,
|
||||||
|
"your tilde.town application was accepted",
|
||||||
|
body)
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,15 +263,16 @@ func _main() error {
|
||||||
updateCount()
|
updateCount()
|
||||||
render()
|
render()
|
||||||
if decision == models.SignupAccepted {
|
if decision == models.SignupAccepted {
|
||||||
if err = invites.InsertInvite(inviteDB, currSignup.CleanEmail); err != nil {
|
invite := &invites.Invite{
|
||||||
|
Email: currSignup.CleanEmail,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = invite.Insert(inviteDB); err != nil {
|
||||||
errorModal.SetText(fmt.Sprintf("error! failed to create invite: %s", err.Error()))
|
errorModal.SetText(fmt.Sprintf("error! failed to create invite: %s", err.Error()))
|
||||||
pages.SwitchToPage("error")
|
pages.SwitchToPage("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO need to get an invite back from InsertInvite so we can send it to
|
if err = sendInviteEmail(*invite); err != nil {
|
||||||
// the clean email using sendInviteEmail
|
|
||||||
|
|
||||||
if err = sendInviteEmail(); err != nil {
|
|
||||||
errorModal.SetText(fmt.Sprintf("error! failed to send welcome email: %s", err.Error()))
|
errorModal.SetText(fmt.Sprintf("error! failed to send welcome email: %s", err.Error()))
|
||||||
pages.SwitchToPage("error")
|
pages.SwitchToPage("error")
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,7 +262,8 @@ func _main(l *log.Logger, db *sql.DB) error {
|
||||||
newScene("done", heredoc.Doc(`
|
newScene("done", heredoc.Doc(`
|
||||||
thank you for applying to tilde.town!
|
thank you for applying to tilde.town!
|
||||||
|
|
||||||
please be on the look out for an email from [-:-:b]root@tilde.town[-:-:-]
|
please be on the look out for an email from [-:-:b]root@tilde.town[-:-:-].
|
||||||
|
it's almost certain that it will end up in your spam filter, unfortunately.
|
||||||
|
|
||||||
you can [-:-:b]/quit[-:-:-] now
|
you can [-:-:b]/quit[-:-:-] now
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SMTPlogin = "root@tilde.town"
|
from = "root@tilde.town"
|
||||||
SMTPHost = "smtp.zoho.com"
|
SMTPHost = "smtp.zoho.com"
|
||||||
SMTPPort = 465
|
SMTPPort = 465
|
||||||
)
|
)
|
||||||
|
@ -39,8 +39,19 @@ func NewExternalMailer(pw string) *ExternalMailer {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ExternalMailer) Send(address, subject, body string) error {
|
func (m *ExternalMailer) Send(address, subject, body string) error {
|
||||||
// TODO need to add headers to prepare message
|
headers := map[string]string{
|
||||||
auth := smtp.PlainAuth("", SMTPlogin, m.Password, SMTPHost)
|
"From": from,
|
||||||
|
"To": address,
|
||||||
|
"Subject": subject,
|
||||||
|
}
|
||||||
|
|
||||||
|
message := ""
|
||||||
|
for k, v := range headers {
|
||||||
|
message += fmt.Sprintf("%s: %s\r\n", k, v)
|
||||||
|
}
|
||||||
|
message += "\r\n" + body
|
||||||
|
|
||||||
|
auth := smtp.PlainAuth("", from, m.Password, SMTPHost)
|
||||||
|
|
||||||
server := fmt.Sprintf("%s:%d", SMTPHost, SMTPPort)
|
server := fmt.Sprintf("%s:%d", SMTPHost, SMTPPort)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,23 @@ type Invite struct {
|
||||||
Used bool
|
Used bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Invite) Insert(db *sql.DB) error {
|
||||||
|
stmt, err := db.Prepare(`
|
||||||
|
INSERT INTO invites (code, email) VALUES (?, ?)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = stmt.Exec(generateCode(i.Email), i.Email)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func ConnectDB() (*sql.DB, error) {
|
func ConnectDB() (*sql.DB, error) {
|
||||||
db, err := sql.Open("sqlite3", dsn)
|
db, err := sql.Open("sqlite3", dsn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -66,23 +83,6 @@ func Decode(code string) ([]string, error) {
|
||||||
return strings.Split(string(decoded), " "), nil
|
return strings.Split(string(decoded), " "), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InsertInvite(db *sql.DB, email string) error {
|
|
||||||
stmt, err := db.Prepare(`
|
|
||||||
INSERT INTO invites (code, email) VALUES (?, ?)
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = stmt.Exec(generateCode(email), email)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer stmt.Close()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Get(db *sql.DB, code string) (*Invite, error) {
|
func Get(db *sql.DB, code string) (*Invite, error) {
|
||||||
inv := &Invite{
|
inv := &Invite{
|
||||||
Code: code,
|
Code: code,
|
||||||
|
|
Loading…
Reference in New Issue