diff --git a/README.md b/README.md index 61876f67..4a083b4b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The mission is to bring software dev inspired features (refactoring, testing, li ## Latest version -v0.42.0 +v0.43.0 ## OS Support diff --git a/app/app/components/layout/zone-content.js b/app/app/components/layout/zone-content.js index cb25c125..f8f457d6 100644 --- a/app/app/components/layout/zone-content.js +++ b/app/app/components/layout/zone-content.js @@ -10,6 +10,18 @@ // https://documize.com import Ember from 'ember'; +import NotifierMixin from '../../mixins/notifier'; -export default Ember.Component.extend({ +const { + inject: { service } +} = Ember; + +export default Ember.Component.extend(NotifierMixin, { + appMeta :service(), + + didRender() { + if (this.get('appMeta').invalidLicense()) { + this.showNotification(`!! Expired or invalid license !!`); + } + } }); diff --git a/app/app/services/app-meta.js b/app/app/services/app-meta.js index 1c8dae9a..1ebf3705 100644 --- a/app/app/services/app-meta.js +++ b/app/app/services/app-meta.js @@ -27,9 +27,15 @@ export default Ember.Service.extend({ title: '', version: '', message: '', + edition: 'Community', + valid: true, allowAnonymousAccess: false, setupMode: false, + invalidLicense() { + return this.valid === false; + }, + getBaseUrl(endpoint) { return [this.get('endpoint'), endpoint].join('/'); }, diff --git a/app/app/services/global.js b/app/app/services/global.js index 830690cc..64bdb24c 100644 --- a/app/app/services/global.js +++ b/app/app/services/global.js @@ -54,7 +54,7 @@ export default Ember.Service.extend({ } }, - // Saves product license + // Saves product license. saveLicense(license) { if(this.get('sessionService.isGlobalAdmin')) { return this.get('ajax').request(`global/license`, { diff --git a/app/app/templates/components/global-settings.hbs b/app/app/templates/components/global-settings.hbs index 5f80caea..26a42073 100644 --- a/app/app/templates/components/global-settings.hbs +++ b/app/app/templates/components/global-settings.hbs @@ -42,7 +42,7 @@
XML format accepted
- {{textarea value=model.license rows="5"}} + {{textarea value=model.license rows="15"}}
save
diff --git a/app/app/utils/net.js b/app/app/utils/net.js index afceec75..8bac8ccf 100644 --- a/app/app/utils/net.js +++ b/app/app/utils/net.js @@ -63,9 +63,22 @@ function isAjaxNotFoundError(reason) { return false; } +function isInvalidLicenseError(reason) { + if (typeof reason === "undefined" || typeof reason.errors === "undefined") { + return false; + } + + if (reason.errors.length > 0 && reason.errors[0].status === "402") { + return true; + } + + return false; +} + export default { getSubdomain, getAppUrl, isAjaxAccessError, isAjaxNotFoundError, + isInvalidLicenseError, }; diff --git a/app/package.json b/app/package.json index 2e0fba82..937279f5 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "documize", - "version": "0.42.0", + "version": "0.43.0", "description": "The Document IDE", "private": true, "repository": "", diff --git a/core/api/endpoint/global_endpoint.go b/core/api/endpoint/global_endpoint.go index 94bcae17..79561fc2 100644 --- a/core/api/endpoint/global_endpoint.go +++ b/core/api/endpoint/global_endpoint.go @@ -109,25 +109,13 @@ func GetLicense(w http.ResponseWriter, r *http.Request) { fmt.Println(err) } - output, err := xml.MarshalIndent(x, " ", " ") + output, err := xml.Marshal(x) if err != nil { fmt.Printf("error: %v\n", err) } w.WriteHeader(http.StatusOK) w.Write(output) - - // // marshal as JSON - // var y map[string]interface{} - // json.Unmarshal([]byte(config), &y) - - // json, err := json.Marshal(y) - // if err != nil { - // writeJSONMarshalError(w, method, "EDITION-LICENSE", err) - // return - // } - - // util.WriteSuccessBytes(w, json) } // SaveLicense persists product license diff --git a/core/api/endpoint/init.go b/core/api/endpoint/init.go index 9c564ad3..98cf53a0 100644 --- a/core/api/endpoint/init.go +++ b/core/api/endpoint/init.go @@ -41,6 +41,11 @@ func writeTransactionError(w http.ResponseWriter, method string, err error) { log.Error(fmt.Sprintf("Unable to get database transaction for method %s", method), err) } +// IsInvalidLicense returns true if license is invalid +func IsInvalidLicense() bool { + return Product.License.Valid == false +} + /* func WriteAddRecordError(w http.ResponseWriter, method string, err error) { w.Header().Set("Content-Type", "application/json; charset=utf-8") diff --git a/core/api/endpoint/label_endpoint.go b/core/api/endpoint/label_endpoint.go index 4d80962d..18a7cf69 100644 --- a/core/api/endpoint/label_endpoint.go +++ b/core/api/endpoint/label_endpoint.go @@ -32,6 +32,11 @@ import ( // AddFolder creates a new folder. func AddFolder(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "AddFolder" p := request.GetPersister(r) @@ -263,6 +268,11 @@ func UpdateFolder(w http.ResponseWriter, r *http.Request) { // RemoveFolder moves documents to another folder before deleting it func RemoveFolder(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "RemoveFolder" p := request.GetPersister(r) diff --git a/core/api/endpoint/meta_endpoint.go b/core/api/endpoint/meta_endpoint.go index b22d421d..61b34572 100644 --- a/core/api/endpoint/meta_endpoint.go +++ b/core/api/endpoint/meta_endpoint.go @@ -45,6 +45,8 @@ func GetMeta(w http.ResponseWriter, r *http.Request) { data.Message = org.Message data.AllowAnonymousAccess = org.AllowAnonymousAccess data.Version = Product.Version + data.Edition = Product.License.Edition + data.Valid = Product.License.Valid json, err := json.Marshal(data) diff --git a/core/api/endpoint/page_endpoint.go b/core/api/endpoint/page_endpoint.go index c606c966..27d89bdc 100644 --- a/core/api/endpoint/page_endpoint.go +++ b/core/api/endpoint/page_endpoint.go @@ -33,6 +33,11 @@ import ( // AddDocumentPage inserts new section into document. func AddDocumentPage(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "AddDocumentPage" p := request.GetPersister(r) @@ -286,6 +291,11 @@ func GetDocumentPagesBatch(w http.ResponseWriter, r *http.Request) { // DeleteDocumentPage deletes a page. func DeleteDocumentPage(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "DeleteDocumentPage" p := request.GetPersister(r) @@ -354,6 +364,11 @@ func DeleteDocumentPage(w http.ResponseWriter, r *http.Request) { // DeleteDocumentPages batch deletes pages. func DeleteDocumentPages(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "DeleteDocumentPages" p := request.GetPersister(r) @@ -433,6 +448,11 @@ func DeleteDocumentPages(w http.ResponseWriter, r *http.Request) { // that this is a new revision. If the page is the first in a document // then the corresponding document title will also be changed. func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "UpdateDocumentPage" p := request.GetPersister(r) params := mux.Vars(r) @@ -540,6 +560,11 @@ func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) { // ChangeDocumentPageSequence will swap page sequence for a given number of pages. func ChangeDocumentPageSequence(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "ChangeDocumentPageSequence" p := request.GetPersister(r) @@ -598,6 +623,11 @@ func ChangeDocumentPageSequence(w http.ResponseWriter, r *http.Request) { // ChangeDocumentPageLevel handles page indent/outdent changes. func ChangeDocumentPageLevel(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "ChangeDocumentPageLevel" p := request.GetPersister(r) @@ -740,6 +770,11 @@ func GetPageMoveCopyTargets(w http.ResponseWriter, r *http.Request) { // GetDocumentRevisions returns all changes for a document. func GetDocumentRevisions(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "GetDocumentPageRevisions" p := request.GetPersister(r) @@ -770,6 +805,11 @@ func GetDocumentRevisions(w http.ResponseWriter, r *http.Request) { // GetDocumentPageRevisions returns all changes for a given page. func GetDocumentPageRevisions(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "GetDocumentPageRevisions" p := request.GetPersister(r) @@ -807,6 +847,11 @@ func GetDocumentPageRevisions(w http.ResponseWriter, r *http.Request) { // GetDocumentPageDiff returns HTML diff between two revisions of a given page. func GetDocumentPageDiff(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "GetDocumentPageDiff" p := request.GetPersister(r) diff --git a/core/api/endpoint/pin_endpoint.go b/core/api/endpoint/pin_endpoint.go index 04f1d1c7..be682241 100644 --- a/core/api/endpoint/pin_endpoint.go +++ b/core/api/endpoint/pin_endpoint.go @@ -28,6 +28,11 @@ import ( // AddPin saves pinned item. func AddPin(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "AddPin" p := request.GetPersister(r) params := mux.Vars(r) @@ -131,6 +136,11 @@ func GetUserPins(w http.ResponseWriter, r *http.Request) { // DeleteUserPin removes saved user pin. func DeleteUserPin(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "DeleteUserPin" p := request.GetPersister(r) params := mux.Vars(r) @@ -175,6 +185,11 @@ func DeleteUserPin(w http.ResponseWriter, r *http.Request) { // UpdatePinSequence records order of pinned items. func UpdatePinSequence(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "UpdatePinSequence" p := request.GetPersister(r) params := mux.Vars(r) diff --git a/core/api/endpoint/sections_endpoint.go b/core/api/endpoint/sections_endpoint.go index f297d815..eaaf8045 100644 --- a/core/api/endpoint/sections_endpoint.go +++ b/core/api/endpoint/sections_endpoint.go @@ -185,6 +185,11 @@ func RefreshSections(w http.ResponseWriter, r *http.Request) { // AddBlock inserts new reusable content block into database. func AddBlock(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "AddBlock" p := request.GetPersister(r) diff --git a/core/api/endpoint/server.go b/core/api/endpoint/server.go index 04b528fb..0387940a 100644 --- a/core/api/endpoint/server.go +++ b/core/api/endpoint/server.go @@ -34,7 +34,7 @@ var Product core.ProdInfo func init() { Product.Major = "0" - Product.Minor = "42" + Product.Minor = "43" Product.Patch = "0" Product.Version = fmt.Sprintf("%s.%s.%s", Product.Major, Product.Minor, Product.Patch) Product.Edition = "Community" diff --git a/core/api/endpoint/templates_endpoint.go b/core/api/endpoint/templates_endpoint.go index 972fbdab..3f12455d 100644 --- a/core/api/endpoint/templates_endpoint.go +++ b/core/api/endpoint/templates_endpoint.go @@ -36,6 +36,11 @@ import ( // SaveAsTemplate saves existing document as a template. func SaveAsTemplate(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "SaveAsTemplate" p := request.GetPersister(r) diff --git a/core/api/endpoint/user_endpoint.go b/core/api/endpoint/user_endpoint.go index 5ababd20..120456d6 100644 --- a/core/api/endpoint/user_endpoint.go +++ b/core/api/endpoint/user_endpoint.go @@ -33,6 +33,11 @@ import ( // AddUser is the endpoint that enables an administrator to add a new user for their orgaisation. func AddUser(w http.ResponseWriter, r *http.Request) { + if IsInvalidLicense() { + util.WriteBadLicense(w) + return + } + method := "AddUser" p := request.GetPersister(r) diff --git a/core/api/entity/objects.go b/core/api/entity/objects.go index e5ffda5c..2e4b4014 100644 --- a/core/api/entity/objects.go +++ b/core/api/entity/objects.go @@ -341,6 +341,8 @@ type SiteMeta struct { URL string `json:"url"` AllowAnonymousAccess bool `json:"allowAnonymousAccess"` Version string `json:"version"` + Edition string `json:"edition"` + Valid bool `json:"valid"` } // Template is used to create a new document. diff --git a/core/api/util/writeHTTP.go b/core/api/util/writeHTTP.go index 68c50ed3..d0a21869 100644 --- a/core/api/util/writeHTTP.go +++ b/core/api/util/writeHTTP.go @@ -164,3 +164,17 @@ func WriteJSON(w http.ResponseWriter, v interface{}) { _, err = w.Write(j) log.IfErr(err) } + +// WriteBadLicense writes 402 when license is invalid +func WriteBadLicense(w http.ResponseWriter) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(http.StatusPaymentRequired) + var e struct { + Reason string + } + e.Reason = "invalid or expired Documize license" + + j, _ := json.Marshal(e) + _, err := w.Write(j) + log.IfErr(err) +}