email accepted users
This commit is contained in:
		
							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,7 +9,7 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	SMTPlogin = "root@tilde.town" | ||||
| 	from     = "root@tilde.town" | ||||
| 	SMTPHost = "smtp.zoho.com" | ||||
| 	SMTPPort = 465 | ||||
| ) | ||||
| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user