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