1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 21:29:42 +02:00

Subscription checks

This commit is contained in:
Harvey Kandola 2018-10-29 16:53:54 +00:00
parent 6e4c5194e2
commit e116d3b000
20 changed files with 211 additions and 76 deletions

122
core/env/product.go vendored
View file

@ -16,9 +16,71 @@ import (
"time" "time"
) )
// ProdInfo describes a product // Edition is either Community or Enterprise.
type ProdInfo struct { type Edition string
Edition string
// Package controls feature-set within edition.
type Package string
// Plan tells us if instance if self-hosted or Documize SaaS/Cloud.
type Plan string
// Seats represents number of users.
type Seats int
const (
// CommunityEdition is AGPL licensed open core of product.
CommunityEdition Edition = "Community"
// EnterpriseEdition is proprietary closed-source product.
EnterpriseEdition Edition = "Enterprise"
// PackageEssentials provides core capabilities.
PackageEssentials Package = "Essentials"
// PackageAdvanced provides analytics, reporting,
// content lifecycle, content verisoning, and audit logs.
PackageAdvanced Package = "Advanced"
// PackagePremium provides actions, feedback capture,
// approvals workflow, secure external sharing.
PackagePremium Package = "Premium"
// PackageDataCenter provides multi-tenanting
// and a bunch of professional services.
PackageDataCenter Package = "Data Center"
// PlanCloud represents *.documize.com hosting.
PlanCloud Plan = "Cloud"
// PlanSelfHost represents privately hosted Documize instance.
PlanSelfHost Plan = "Self-host"
// Seats0 is 0 users.
Seats0 Seats = 0
// Seats1 is 10 users.
Seats1 Seats = 10
// Seats2 is 25 users.
Seats2 Seats = 25
//Seats3 is 50 users.
Seats3 Seats = 50
// Seats4 is 100 users.
Seats4 Seats = 100
//Seats5 is 250 users.
Seats5 Seats = 250
// Seats6 is unlimited.
Seats6 Seats = 9999
)
// Product provides meta information about product and licensing.
type Product struct {
Edition Edition
Title string Title string
Version string Version string
Major string Major string
@ -28,42 +90,66 @@ type ProdInfo struct {
License License License License
} }
// License holds details of product license. // License provides details of product license.
type License struct { type License struct {
Name string `json:"name"` Name string `json:"name"`
Email string `json:"email"` Email string `json:"email"`
Edition string `json:"edition"` Edition Edition `json:"edition"`
Package string `json:"package"` Package Package `json:"package"`
Plan string `json:"plan"` Plan Plan `json:"plan"`
Start time.Time `json:"start"` Start time.Time `json:"start"`
End time.Time `json:"end"` End time.Time `json:"end"`
Seats int `json:"seats"` Seats Seats `json:"seats"`
Trial bool `json:"trial"` Trial bool `json:"trial"`
Valid bool `json:"valid"`
// UserCount is number of users within Documize instance by tenant.
// Provided at runtime.
UserCount map[string]int
} }
// IsEmpty determines if we have a license. // IsEmpty determines if we have a license.
func (l *License) IsEmpty() bool { func (l *License) IsEmpty() bool {
return l.Seats == 0 && len(l.Name) == 0 && len(l.Email) == 0 && l.Start.Year() == 1 && l.End.Year() == 1 return l.Seats == Seats0 &&
len(l.Name) == 0 && len(l.Email) == 0 && l.Start.Year() == 1 && l.End.Year() == 1
} }
// Status returns formatted message stating if license is empty/populated and invalid/valid. // Status returns formatted message stating if license is empty/populated and invalid/valid.
func (l *License) Status() string { func (l *License) Status(orgID string) string {
lp := "populated" lp := "populated"
if l.IsEmpty() { if l.IsEmpty() {
lp = "empty" lp = "empty"
} }
lv := "invalid" lv := "invalid"
if l.Valid { if l.IsValid(orgID) {
lv = "valid" lv = "valid"
} }
return fmt.Sprintf("License is %s and %s", lp, lv) return fmt.Sprintf("License is %s and %s", lp, lv)
} }
// IsValid returns if license is valid // IsValid returns if license is valid for specified tenant.
func (l *License) IsValid() bool { func (l *License) IsValid(orgID string) bool {
return l.Valid == true valid := false
// Community edition is always valid.
if l.Edition == CommunityEdition {
valid = true
}
// Enterprise edition is valid if subcription date is
// greater than now and we have enough users/seats.
if l.Edition == EnterpriseEdition {
if time.Now().UTC().Before(l.End) && l.UserCount[orgID] <= int(l.Seats) {
valid = true
}
}
// Empty means we cannot be valid
if l.IsEmpty() || len(l.UserCount) == 0 {
valid = false
}
return valid
} }
// LicenseData holds encrypted data and is unpacked into License. // LicenseData holds encrypted data and is unpacked into License.
@ -71,3 +157,9 @@ type LicenseData struct {
Key string `json:"key"` Key string `json:"key"`
Signature string `json:"signature"` Signature string `json:"signature"`
} }
// LicenseUserAcount states number of active users by tenant.
type LicenseUserAcount struct {
OrgID string `json:"orgId"`
Users int `json:"users"`
}

10
core/env/runtime.go vendored
View file

@ -23,7 +23,7 @@ type Runtime struct {
Db *sqlx.DB Db *sqlx.DB
StoreProvider StoreProvider StoreProvider StoreProvider
Log Logger Log Logger
Product ProdInfo Product Product
} }
const ( const (
@ -39,11 +39,3 @@ const (
// SiteModeBadDB redirects to db-error.html page // SiteModeBadDB redirects to db-error.html page
SiteModeBadDB = "3" SiteModeBadDB = "3"
) )
const (
// CommunityEdition is AGPL product variant
CommunityEdition = "Community"
// EnterpriseEdition is commercial licensed product variant
EnterpriseEdition = "Enterprise"
)

View file

@ -23,6 +23,7 @@ func StripAuthSecrets(r *env.Runtime, provider, config string) string {
switch provider { switch provider {
case auth.AuthProviderDocumize: case auth.AuthProviderDocumize:
return config return config
case auth.AuthProviderKeycloak: case auth.AuthProviderKeycloak:
c := auth.KeycloakConfig{} c := auth.KeycloakConfig{}
err := json.Unmarshal([]byte(config), &c) err := json.Unmarshal([]byte(config), &c)
@ -41,6 +42,7 @@ func StripAuthSecrets(r *env.Runtime, provider, config string) string {
} }
return string(j) return string(j)
case auth.AuthProviderLDAP: case auth.AuthProviderLDAP:
c := auth.LDAPConfig{} c := auth.LDAPConfig{}
err := json.Unmarshal([]byte(config), &c) err := json.Unmarshal([]byte(config), &c)

View file

@ -206,7 +206,7 @@ func (b backerHandler) produce(id string) (files []backupItem, err error) {
func (b backerHandler) manifest(id string) (string, error) { func (b backerHandler) manifest(id string) (string, error) {
m := m.Manifest{ m := m.Manifest{
ID: id, ID: id,
Edition: b.Runtime.Product.Edition, Edition: b.Runtime.Product.License.Edition,
Version: b.Runtime.Product.Version, Version: b.Runtime.Product.Version,
Major: b.Runtime.Product.Major, Major: b.Runtime.Product.Major,
Minor: b.Runtime.Product.Minor, Minor: b.Runtime.Product.Minor,

View file

@ -39,7 +39,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
method := "block.add" method := "block.add"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }

View file

@ -60,7 +60,7 @@ func (h *Handler) Meta(w http.ResponseWriter, r *http.Request) {
data.Version = h.Runtime.Product.Version data.Version = h.Runtime.Product.Version
data.Revision = h.Runtime.Product.Revision data.Revision = h.Runtime.Product.Revision
data.Edition = h.Runtime.Product.Edition data.Edition = h.Runtime.Product.Edition
data.Valid = h.Runtime.Product.License.Valid data.Valid = h.Runtime.Product.License.IsValid(org.RefID)
data.ConversionEndpoint = org.ConversionEndpoint data.ConversionEndpoint = org.ConversionEndpoint
data.License = h.Runtime.Product.License data.License = h.Runtime.Product.License
data.Storage = h.Runtime.StoreProvider.Type() data.Storage = h.Runtime.StoreProvider.Type()

View file

@ -52,7 +52,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
method := "page.add" method := "page.add"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -322,7 +322,7 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
method := "page.update" method := "page.update"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -510,7 +510,7 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
method := "page.delete" method := "page.delete"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -608,7 +608,7 @@ func (h *Handler) DeletePages(w http.ResponseWriter, r *http.Request) {
method := "page.delete.pages" method := "page.delete.pages"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -721,7 +721,7 @@ func (h *Handler) ChangePageSequence(w http.ResponseWriter, r *http.Request) {
method := "page.sequence" method := "page.sequence"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -791,7 +791,7 @@ func (h *Handler) ChangePageLevel(w http.ResponseWriter, r *http.Request) {
method := "page.level" method := "page.level"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -987,7 +987,7 @@ func (h *Handler) GetDocumentRevisions(w http.ResponseWriter, r *http.Request) {
method := "page.document.revisions" method := "page.document.revisions"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -1018,7 +1018,7 @@ func (h *Handler) GetRevisions(w http.ResponseWriter, r *http.Request) {
method := "page.revisions" method := "page.revisions"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -1053,7 +1053,7 @@ func (h *Handler) GetDiff(w http.ResponseWriter, r *http.Request) {
method := "page.diff" method := "page.diff"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }

View file

@ -45,7 +45,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
return return
} }
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -154,7 +154,7 @@ func (h *Handler) DeleteUserPin(w http.ResponseWriter, r *http.Request) {
return return
} }
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -198,7 +198,7 @@ func (h *Handler) UpdatePinSequence(w http.ResponseWriter, r *http.Request) {
return return
} }
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }

View file

@ -57,7 +57,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
method := "space.add" method := "space.add"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -582,7 +582,7 @@ func (h *Handler) Remove(w http.ResponseWriter, r *http.Request) {
method := "space.remove" method := "space.remove"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }
@ -675,7 +675,7 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
method := "space.delete" method := "space.delete"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }

View file

@ -12,6 +12,7 @@
package store package store
import ( import (
"github.com/documize/community/core/env"
"github.com/documize/community/domain" "github.com/documize/community/domain"
"github.com/documize/community/model/account" "github.com/documize/community/model/account"
"github.com/documize/community/model/activity" "github.com/documize/community/model/activity"
@ -122,7 +123,7 @@ type UserStorer interface {
UpdateUserPassword(ctx domain.RequestContext, userID, salt, password string) (err error) UpdateUserPassword(ctx domain.RequestContext, userID, salt, password string) (err error)
DeactiveUser(ctx domain.RequestContext, userID string) (err error) DeactiveUser(ctx domain.RequestContext, userID string) (err error)
ForgotUserPassword(ctx domain.RequestContext, email, token string) (err error) ForgotUserPassword(ctx domain.RequestContext, email, token string) (err error)
CountActiveUsers() (c int) CountActiveUsers() (c []env.LicenseUserAcount)
MatchUsers(ctx domain.RequestContext, text string, maxMatches int) (u []user.User, err error) MatchUsers(ctx domain.RequestContext, text string, maxMatches int) (u []user.User, err error)
} }

View file

@ -90,7 +90,7 @@ func (h *Handler) SaveAs(w http.ResponseWriter, r *http.Request) {
method := "template.saved" method := "template.saved"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
return return
} }

View file

@ -2,6 +2,7 @@ package test
import ( import (
"fmt" "fmt"
"github.com/documize/community/domain/store"
"github.com/documize/community/core/env" "github.com/documize/community/core/env"
"github.com/documize/community/domain" "github.com/documize/community/domain"
@ -13,20 +14,21 @@ import (
) )
// SetupTest prepares test environment // SetupTest prepares test environment
func SetupTest() (rt *env.Runtime, s *domain.Store, ctx domain.RequestContext) { func SetupTest() (rt *env.Runtime, s *store
.Store, ctx domain.RequestContext) {
rt, s = startRuntime() rt, s = startRuntime()
ctx = setupContext() ctx = setupContext()
return rt, s, ctx return rt, s, ctx
} }
func startRuntime() (rt *env.Runtime, s *domain.Store) { func startRuntime() (rt *env.Runtime, s *store.Store) {
rt = new(env.Runtime) rt = new(env.Runtime)
s = new(domain.Store) s = new(store.Store)
rt.Log = logging.NewLogger(false) rt.Log = logging.NewLogger(false)
web.Embed = embed.NewEmbedder() web.Embed = embed.NewEmbedder()
rt.Product = env.ProdInfo{} rt.Product = env.Product{}
rt.Product.Major = "0" rt.Product.Major = "0"
rt.Product.Minor = "0" rt.Product.Minor = "0"
rt.Product.Patch = "0" rt.Product.Patch = "0"
@ -35,9 +37,8 @@ func startRuntime() (rt *env.Runtime, s *domain.Store) {
rt.Product.Title = fmt.Sprintf("%s Edition", rt.Product.Edition) rt.Product.Title = fmt.Sprintf("%s Edition", rt.Product.Edition)
rt.Product.License = env.License{} rt.Product.License = env.License{}
rt.Product.License.Seats = 1 rt.Product.License.Seats = 1
rt.Product.License.Valid = true
rt.Product.License.Trial = false rt.Product.License.Trial = false
rt.Product.License.Edition = "Community" rt.Product.License.Edition = env.CommunityEdition
// parse settings from command line and environment // parse settings from command line and environment
rt.Flags = env.ParseFlags() rt.Flags = env.ParseFlags()
@ -56,7 +57,7 @@ func setupContext() domain.RequestContext {
ctx.Administrator = true ctx.Administrator = true
ctx.Guest = false ctx.Guest = false
ctx.Editor = true ctx.Editor = true
ctx.Global = true ctx.GlobalAdmin = true
ctx.UserID = "test" ctx.UserID = "test"
ctx.OrgID = "test" ctx.OrgID = "test"
return ctx return ctx

View file

@ -51,7 +51,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
method := "user.Add" method := "user.Add"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
if !h.Runtime.Product.License.IsValid() { if !h.Runtime.Product.License.IsValid(ctx.OrgID) {
response.WriteBadLicense(w) response.WriteBadLicense(w)
} }

View file

@ -14,6 +14,7 @@ package user
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/documize/community/core/env"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -312,17 +313,11 @@ func (s Store) ForgotUserPassword(ctx domain.RequestContext, email, token string
} }
// CountActiveUsers returns the number of active users in the system. // CountActiveUsers returns the number of active users in the system.
func (s Store) CountActiveUsers() (c int) { func (s Store) CountActiveUsers() (c []env.LicenseUserAcount) {
row := s.Runtime.Db.QueryRow("SELECT count(*) FROM dmz_user WHERE c_refid IN (SELECT c_userid FROM dmz_user_account WHERE c_active=true)") err := s.Runtime.Db.Select(&c, "SELECT c_orgid AS orgid, COUNT(*) AS users FROM dmz_user_account WHERE c_active=true GROUP BY c_orgid ORDER BY c_orgid")
err := row.Scan(&c)
if err == sql.ErrNoRows {
return 0
}
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
s.Runtime.Log.Error("CountActiveUsers", err) s.Runtime.Log.Error("CountActiveUsers", err)
return 0
} }
return return

View file

@ -14,6 +14,7 @@ package main
import ( import (
"fmt" "fmt"
"time"
"github.com/documize/community/core/env" "github.com/documize/community/core/env"
"github.com/documize/community/domain/section" "github.com/documize/community/domain/section"
@ -36,21 +37,20 @@ func main() {
web.Embed = embed.NewEmbedder() web.Embed = embed.NewEmbedder()
// product details // product details
rt.Product = env.ProdInfo{} rt.Product = env.Product{}
rt.Product.Major = "1" rt.Product.Major = "1"
rt.Product.Minor = "72" rt.Product.Minor = "72"
rt.Product.Patch = "1" rt.Product.Patch = "1"
rt.Product.Revision = 181022154519 rt.Product.Revision = 181022154519
rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch) rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch)
rt.Product.Edition = "Community" rt.Product.Edition = env.CommunityEdition
rt.Product.Title = fmt.Sprintf("%s Edition", rt.Product.Edition) rt.Product.Title = fmt.Sprintf("%s Edition", rt.Product.Edition)
rt.Product.License = env.License{}
rt.Product.License.Seats = 1
rt.Product.License.Valid = true
rt.Product.License.Trial = false
rt.Product.License.Edition = "Community"
// setup store // Community edition is good to go with no user limits.
rt.Product.License = env.License{Edition: env.CommunityEdition, Seats: env.Seats6, Trial: false,
Start: time.Now().UTC(), End: time.Now().UTC().Add(time.Hour * 24 * 7 * time.Duration(52))}
// Setup data store.
s := store.Store{} s := store.Store{}
// parse settings from command line and environment // parse settings from command line and environment

View file

@ -141,6 +141,58 @@ let constants = EmberObject.extend({
MySQL: 'MySQL', MySQL: 'MySQL',
PostgreSQL: 'PostgreSQL', PostgreSQL: 'PostgreSQL',
}, },
// Product is where we try to balance the fine line between useful open core
// and the revenue-generating proprietary edition.
Product: { // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
// CommunityEdition is AGPL licensed open core of product.
CommunityEdition: 'Community',
// EnterpriseEdition is proprietary closed-source product.
EnterpriseEdition: 'Enterprise',
// PackageEssentials provides core capabilities.
PackageEssentials: "Essentials",
// PackageAdvanced provides analytics, reporting,
// content lifecycle, content verisoning, and audit logs.
PackageAdvanced: "Advanced",
// PackagePremium provides actions, feedback capture,
// approvals workflow, secure external sharing.
PackagePremium: "Premium",
// PackageDataCenter provides multi-tenanting
// and a bunch of professional services.
PackageDataCenter: "Data Center",
// PlanCloud represents *.documize.com hosting.
PlanCloud: "Cloud",
// PlanSelfHost represents privately hosted Documize instance.
PlanSelfHost: "Self-host",
// Seats0 is 0 users.
Seats0: 0,
// Seats1 is 10 users.
Seats1: 10,
// Seats2 is 25 users.
Seats2: 25,
//Seats3 is 50 users.
Seats3: 50,
// Seats4 is 100 users.
Seats4: 100,
//Seats5 is 250 users.
Seats5: 250,
// Seats6 is unlimited.
Seats6: 9999
}
}); });
export default { constants } export default { constants }

View file

@ -15,7 +15,7 @@
<label for="product-license-xml">Optional Enterprise Edition License Key</label> <label for="product-license-xml">Optional Enterprise Edition License Key</label>
{{textarea id="product-license-xml" value=license rows="18" class=(if LicenseError 'form-control is-invalid' 'form-control')}} {{textarea id="product-license-xml" value=license rows="18" class=(if LicenseError 'form-control is-invalid' 'form-control')}}
{{#if appMeta.valid}} {{#if appMeta.valid}}
{{#if (eq appMeta.edition "Enterprise")}} {{#if (eq appMeta.edition constants.Product.EnterpriseEdition)}}
<p class="mt-2 color-green">Registered to {{appMeta.license.email}} @ {{appMeta.license.name}}</p> <p class="mt-2 color-green">Registered to {{appMeta.license.email}} @ {{appMeta.license.name}}</p>
<p class="mt-2 color-green">{{appMeta.license.package}} package up to {{appMeta.license.seats}} users</p> <p class="mt-2 color-green">{{appMeta.license.package}} package up to {{appMeta.license.seats}} users</p>
{{#if appMeta.license.trial}} {{#if appMeta.license.trial}}

View file

@ -7,12 +7,12 @@
<li class="item cursor-auto"> <li class="item cursor-auto">
<img class="logo" src="/assets/img/icon-white-64x64.png" /> <img class="logo" src="/assets/img/icon-white-64x64.png" />
</li> </li>
{{#if (eq appMeta.edition 'Community')}} {{#if (eq appMeta.edition constants.Product.CommunityEdition)}}
<li class="item"> <li class="item">
{{#link-to "folders" class=(if (eq selectItem 'spaces') 'link selected' 'link')}}SPACES{{/link-to}} {{#link-to "folders" class=(if (eq selectItem 'spaces') 'link selected' 'link')}}SPACES{{/link-to}}
</li> </li>
{{/if}} {{/if}}
{{#if (eq appMeta.edition 'Enterprise')}} {{#if (eq appMeta.edition constants.Product.EnterpriseEdition)}}
{{#if session.viewDashboard}} {{#if session.viewDashboard}}
<li class="item"> <li class="item">
{{#link-to "dashboard" class=(if (eq selectItem 'dashboard') 'link selected' 'link')}}ACTIONS{{/link-to}} {{#link-to "dashboard" class=(if (eq selectItem 'dashboard') 'link selected' 'link')}}ACTIONS{{/link-to}}
@ -36,10 +36,10 @@
<i class="material-icons">menu</i> <i class="material-icons">menu</i>
</div> </div>
<div class="dropdown-menu" aria-labelledby="top-nav-hamburger"> <div class="dropdown-menu" aria-labelledby="top-nav-hamburger">
{{#if (eq appMeta.edition 'Community')}} {{#if (eq appMeta.edition constants.Product.CommunityEdition)}}
{{#link-to "folders" class="dropdown-item"}}Spaces{{/link-to}} {{#link-to "folders" class="dropdown-item"}}Spaces{{/link-to}}
{{/if}} {{/if}}
{{#if (eq appMeta.edition 'Enterprise')}} {{#if (eq appMeta.edition constants.Product.EnterpriseEdition)}}
{{#link-to "folders" class="dropdown-item"}}Spaces{{/link-to}} {{#link-to "folders" class="dropdown-item"}}Spaces{{/link-to}}
{{#if session.viewDashboard}} {{#if session.viewDashboard}}
{{#link-to "dashboard" class="dropdown-item"}}Actions{{/link-to}} {{#link-to "dashboard" class="dropdown-item"}}Actions{{/link-to}}
@ -178,7 +178,7 @@
<div class="dotcom"> <div class="dotcom">
<a href="https://documize.com">https://documize.com</a> <a href="https://documize.com">https://documize.com</a>
</div> </div>
{{#if (eq appMeta.edition 'Community')}} {{#if (eq appMeta.edition constants.Product.CommunityEdition)}}
<div class="copyright"> <div class="copyright">
&copy; Documize Inc. All rights reserved. &copy; Documize Inc. All rights reserved.
</div> </div>

View file

@ -30,7 +30,7 @@ type Manifest struct {
OrgID string `json:"org"` OrgID string `json:"org"`
// Product edition at the time of the backup. // Product edition at the time of the backup.
Edition string `json:"edition"` Edition env.Edition `json:"edition"`
// When the backup took place. // When the backup took place.
Created time.Time `json:"created"` Created time.Time `json:"created"`

View file

@ -38,7 +38,7 @@ type SiteMeta struct {
Version string `json:"version"` Version string `json:"version"`
Revision int `json:"revision"` Revision int `json:"revision"`
MaxTags int `json:"maxTags"` MaxTags int `json:"maxTags"`
Edition string `json:"edition"` Edition env.Edition `json:"edition"`
Valid bool `json:"valid"` Valid bool `json:"valid"`
ConversionEndpoint string `json:"conversionEndpoint"` ConversionEndpoint string `json:"conversionEndpoint"`
License env.License `json:"license"` License env.License `json:"license"`