Page MenuHomeMusing Studio

No OneTemporary

diff --git a/invites.go b/invites.go
index f7dcd7a..f9c5cce 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
InviteID string
Expired bool
}{
- UserPage: NewUserPage(app, r, u, "Invite Instructions", nil),
+ UserPage: NewUserPage(app, r, u, "Invite to "+app.cfg.App.SiteName, nil),
InviteID: inviteCode,
Expired: expired,
}
showUserPage(w, "invite-instructions", 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-instructions.tmpl
index a70acd8..c99680a 100644
--- a/templates/user/invite-instructions.tmpl
+++ b/templates/user/invite-instructions.tmpl
@@ -1,29 +1,23 @@
{{define "invite-instructions"}}
{{template "header" .}}
<style>
.copy-link {
width: 100%;
margin: 2em 0;
text-align: center;
font-size-adjust: .7;
color: #555;
}
</style>
<div class="snug content-container">
- <h1>Invite Instructions</h1>
+ <h1>Invite to {{.SiteName}}</h1>
{{ if .Expired }}
<p style="font-style: italic">This invite link is expired.</p>
{{ else }}
- <p>This is a special link that you can send to anyone you want to join <em>{{ .SiteName }}</em>. 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.</p>
- <input
- class="copy-link"
- type="text"
- name="invite-url"
- value="{{$.Host}}/invite/{{.InviteID}}"
- onfocus="if (this.select) this.select(); else this.setSelectionRange(0, this.value.length);"
- readonly/>
+ <p>Copy the link below and send it to anyone that you want to join <em>{{ .SiteName }}</em>. 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.</p>
+ <input class="copy-link" type="text" name="invite-url" value="{{$.Host}}/invite/{{.InviteID}}" onfocus="if (this.select) this.select(); else this.setSelectionRange(0, this.value.length);" readonly />
{{ end }}
</div>
{{template "footer" .}}
{{end}}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Mar 6, 10:33 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3168310

Event Timeline