diff --git a/database.go b/database.go index 730bb60..a3235b6 100644 --- a/database.go +++ b/database.go @@ -2257,6 +2257,19 @@ func (db *datastore) GetUserInvite(id string) (*Invite, error) { return &i, nil } +// IsUsersInvite returns true if the user with ID created the invite with code +// and an error other than sql no rows, if any. Will return false in the event +// of an error. +func (db *datastore) IsUsersInvite(code string, userID int64) (bool, error) { + var id string + err := db.QueryRow("SELECT id FROM userinvites WHERE id = ? AND owner_id = ?", code, userID).Scan(&id) + if err != nil && err != sql.ErrNoRows { + log.Error("Failed selecting invite: %v", err) + return false, err + } + return id != "", nil +} + func (db *datastore) GetUsersInvitedCount(id string) int64 { var count int64 err := db.QueryRow("SELECT COUNT(*) FROM usersinvited WHERE invite_id = ?", id).Scan(&count) diff --git a/invites.go b/invites.go index 561255f..1e58ac3 100644 --- a/invites.go +++ b/invites.go @@ -12,15 +12,16 @@ 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" - "html/template" - "net/http" - "strconv" - "time" ) type Invite struct { @@ -109,6 +110,26 @@ func handleCreateUserInvite(app *App, u *User, w http.ResponseWriter, r *http.Re func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error { inviteCode := mux.Vars(r)["code"] + 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 + InviteID string + }{ + UserPage: NewUserPage(app, r, u, "Invite Instructions", nil), + InviteID: inviteCode, + } + showUserPage(w, "invite-instructions", p) + return nil + } + i, err := app.db.GetUserInvite(inviteCode) if err != nil { return err diff --git a/routes.go b/routes.go index 777492b..0113e93 100644 --- a/routes.go +++ b/routes.go @@ -11,13 +11,14 @@ package writefreely import ( + "net/http" + "path/filepath" + "strings" + "github.com/gorilla/mux" "github.com/writeas/go-webfinger" "github.com/writeas/web-core/log" "github.com/writefreely/go-nodeinfo" - "net/http" - "path/filepath" - "strings" ) // InitStaticRoutes adds routes for serving static files. @@ -151,7 +152,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router { // Handle special pages first write.HandleFunc("/login", handler.Web(viewLogin, UserLevelNoneRequired)) write.HandleFunc("/signup", handler.Web(handleViewLanding, UserLevelNoneRequired)) - write.HandleFunc("/invite/{code}", handler.Web(handleViewInvite, UserLevelNoneRequired)).Methods("GET") + write.HandleFunc("/invite/{code}", handler.Web(handleViewInvite, UserLevelOptional)).Methods("GET") // TODO: show a reader-specific 404 page if the function is disabled write.HandleFunc("/read", handler.Web(viewLocalTimeline, UserLevelReader)) RouteRead(handler, UserLevelReader, write.PathPrefix("/read").Subrouter()) diff --git a/templates/user/invite-instructions.tmpl b/templates/user/invite-instructions.tmpl new file mode 100644 index 0000000..8bd2a30 --- /dev/null +++ b/templates/user/invite-instructions.tmpl @@ -0,0 +1,25 @@ +{{define "invite-instructions"}} +{{template "header" .}} + +
+

Invite Instructions

+

This is a special link that you can send to anyone you want to join {{ .SiteName }}. Copy the link below and paste it into an email, instant message, or text message and send it to the person you want. When they navigate to the link, they'll be able to create an account.

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