forked from tildetown/town
email accepted users
parent
cee8b75bad
commit
c43adc49fb
|
@ -1,8 +1,67 @@
|
|||
package main
|
||||
|
||||
// TODO function for reading smtp.pw from /town/docs
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
func sendInviteEmail() error {
|
||||
// TODO
|
||||
return nil
|
||||
"git.tilde.town/tildetown/town/email"
|
||||
"git.tilde.town/tildetown/town/invites"
|
||||
)
|
||||
|
||||
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()
|
||||
render()
|
||||
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()))
|
||||
pages.SwitchToPage("error")
|
||||
}
|
||||
|
||||
// TODO need to get an invite back from InsertInvite so we can send it to
|
||||
// the clean email using sendInviteEmail
|
||||
|
||||
if err = sendInviteEmail(); err != nil {
|
||||
if err = sendInviteEmail(*invite); err != nil {
|
||||
errorModal.SetText(fmt.Sprintf("error! failed to send welcome email: %s", err.Error()))
|
||||
pages.SwitchToPage("error")
|
||||
}
|
||||
|
|
|
@ -262,7 +262,8 @@ func _main(l *log.Logger, db *sql.DB) error {
|
|||
newScene("done", heredoc.Doc(`
|
||||
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
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SMTPlogin = "root@tilde.town"
|
||||
SMTPHost = "smtp.zoho.com"
|
||||
SMTPPort = 465
|
||||
from = "root@tilde.town"
|
||||
SMTPHost = "smtp.zoho.com"
|
||||
SMTPPort = 465
|
||||
)
|
||||
|
||||
func SendLocalEmail(username, subject, body string) error {
|
||||
|
@ -39,8 +39,19 @@ func NewExternalMailer(pw string) *ExternalMailer {
|
|||
}
|
||||
|
||||
func (m *ExternalMailer) Send(address, subject, body string) error {
|
||||
// TODO need to add headers to prepare message
|
||||
auth := smtp.PlainAuth("", SMTPlogin, m.Password, SMTPHost)
|
||||
headers := map[string]string{
|
||||
"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)
|
||||
|
||||
|
|
|
@ -24,6 +24,23 @@ type Invite struct {
|
|||
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) {
|
||||
db, err := sql.Open("sqlite3", dsn)
|
||||
if err != nil {
|
||||
|
@ -66,23 +83,6 @@ func Decode(code string) ([]string, error) {
|
|||
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) {
|
||||
inv := &Invite{
|
||||
Code: code,
|
||||
|
|
Loading…
Reference in New Issue