diff --git a/invites.go b/invites.go index 2320906..3e19d7e 100644 --- a/invites.go +++ b/invites.go @@ -1,175 +1,175 @@ /* * Copyright © 2019 A Bunch Tell LLC. * * This file is part of WriteFreely. * * WriteFreely is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, included * in the LICENSE file in this source code package. */ package writefreely import ( "database/sql" "html/template" "net/http" "strconv" "time" "github.com/gorilla/mux" "github.com/writeas/impart" "github.com/writeas/nerds/store" "github.com/writeas/web-core/log" "github.com/writeas/writefreely/page" ) type Invite struct { ID string MaxUses sql.NullInt64 Created time.Time Expires *time.Time Inactive bool uses int64 } func (i Invite) Uses() int64 { return i.uses } func (i Invite) Expired() bool { return i.Expires != nil && i.Expires.Before(time.Now()) } func (i Invite) ExpiresFriendly() string { return i.Expires.Format("January 2, 2006, 3:04 PM") } func handleViewUserInvites(app *App, u *User, w http.ResponseWriter, r *http.Request) error { // Don't show page if instance doesn't allow it if !(app.cfg.App.UserInvites != "" && (u.IsAdmin() || app.cfg.App.UserInvites != "admin")) { return impart.HTTPError{http.StatusNotFound, ""} } f, _ := getSessionFlashes(app, w, r, nil) p := struct { *UserPage Invites *[]Invite }{ UserPage: NewUserPage(app, r, u, "Invite People", f), } var err error p.Invites, err = app.db.GetUserInvites(u.ID) if err != nil { return err } for i := range *p.Invites { (*p.Invites)[i].uses = app.db.GetUsersInvitedCount((*p.Invites)[i].ID) } showUserPage(w, "invite", p) return nil } func handleCreateUserInvite(app *App, u *User, w http.ResponseWriter, r *http.Request) error { muVal := r.FormValue("uses") expVal := r.FormValue("expires") var err error var maxUses int if muVal != "0" { maxUses, err = strconv.Atoi(muVal) if err != nil { return impart.HTTPError{http.StatusBadRequest, "Invalid value for 'max_uses'"} } } var expDate *time.Time var expires int if expVal != "0" { expires, err = strconv.Atoi(expVal) if err != nil { return impart.HTTPError{http.StatusBadRequest, "Invalid value for 'expires'"} } ed := time.Now().Add(time.Duration(expires) * time.Minute) expDate = &ed } inviteID := store.GenerateRandomString("0123456789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz", 6) err = app.db.CreateUserInvite(inviteID, u.ID, maxUses, expDate) if err != nil { return err } return impart.HTTPError{http.StatusFound, "/me/invites"} } func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error { inviteCode := mux.Vars(r)["code"] i, err := app.db.GetUserInvite(inviteCode) if err != nil { return err } expired := i.Expired() if !expired && i.MaxUses.Valid && i.MaxUses.Int64 > 0 { // Invite has a max-use number, so check if we're past that limit i.uses = app.db.GetUsersInvitedCount(inviteCode) expired = i.uses >= i.MaxUses.Int64 } if u := getUserSession(app, r); u != nil { // check if invite belongs to another user // error can be ignored as not important in this case if ownInvite, _ := app.db.IsUsersInvite(inviteCode, u.ID); !ownInvite { addSessionFlash(app, w, r, "No need for an invite, You are already registered.", nil) // show homepage return impart.HTTPError{http.StatusFound, "/me/settings"} } // show invite instructions p := struct { *UserPage Invite *Invite Expired bool }{ UserPage: NewUserPage(app, r, u, "Invite to "+app.cfg.App.SiteName, nil), Invite: i, Expired: expired, } - showUserPage(w, "invite-instructions", p) + showUserPage(w, "invite-help", p) return nil } p := struct { page.StaticPage Error string Flashes []template.HTML Invite string }{ StaticPage: pageForReq(app, r), Invite: inviteCode, } if expired { p.Error = "This invite link has expired." } // Get error messages session, err := app.sessionStore.Get(r, cookieName) if err != nil { // Ignore this log.Error("Unable to get session in handleViewInvite; ignoring: %v", err) } flashes, _ := getSessionFlashes(app, w, r, session) for _, flash := range flashes { p.Flashes = append(p.Flashes, template.HTML(flash)) } // Show landing page return renderPage(w, "signup.tmpl", p) } diff --git a/templates/user/invite-instructions.tmpl b/templates/user/invite-help.tmpl similarity index 97% rename from templates/user/invite-instructions.tmpl rename to templates/user/invite-help.tmpl index e31e778..978cfad 100644 --- a/templates/user/invite-instructions.tmpl +++ b/templates/user/invite-help.tmpl @@ -1,32 +1,32 @@ -{{define "invite-instructions"}} +{{define "invite-help"}} {{template "header" .}}

Invite to {{.SiteName}}

{{ if .Expired }}

This invite link is expired.

{{ else }}

Copy the link below and send it to anyone that you want to join {{ .SiteName }}. You could paste it into an email, instant message, text message, or write it down on paper. Anyone who navigates to this special page will be able to create an account.

{{ if gt .Invite.MaxUses.Int64 0 }} {{if eq .Invite.MaxUses.Int64 1}}Only one user{{else}}Up to {{.Invite.MaxUses.Int64}} users{{end}} can sign up with this link. {{if gt .Invite.Uses 0}}So far, {{.Invite.Uses}} {{pluralize "person has" "people have" .Invite.Uses}} used it.{{end}} {{if .Invite.Expires}}It expires on {{.Invite.ExpiresFriendly}}.{{end}} {{ else }} It can be used as many times as you like{{if .Invite.Expires}} before {{.Invite.ExpiresFriendly}}, when it expires{{end}}. {{ end }}

{{ end }}
{{template "footer" .}} {{end}}