mirror of
https://github.com/documize/community.git
synced 2025-07-19 05:09:42 +02:00
Accept activation key during setup process
Enterprise edition only.
This commit is contained in:
parent
887c999a1e
commit
4d2f30711c
11 changed files with 161 additions and 52 deletions
|
@ -12,6 +12,8 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
@ -21,6 +23,7 @@ import (
|
|||
"github.com/documize/community/core/secrets"
|
||||
"github.com/documize/community/core/stringutil"
|
||||
"github.com/documize/community/core/uniqueid"
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/documize/community/domain/store"
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
@ -65,15 +68,16 @@ func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
details := onboardRequest{
|
||||
URL: "",
|
||||
Company: r.Form.Get("title"),
|
||||
CompanyLong: r.Form.Get("title"),
|
||||
Message: r.Form.Get("message"),
|
||||
Email: r.Form.Get("email"),
|
||||
Password: r.Form.Get("password"),
|
||||
Firstname: r.Form.Get("firstname"),
|
||||
Lastname: r.Form.Get("lastname"),
|
||||
Revised: time.Now().UTC(),
|
||||
URL: "",
|
||||
Company: r.Form.Get("title"),
|
||||
CompanyLong: r.Form.Get("title"),
|
||||
Message: r.Form.Get("message"),
|
||||
Email: r.Form.Get("email"),
|
||||
Password: r.Form.Get("password"),
|
||||
Firstname: r.Form.Get("firstname"),
|
||||
Lastname: r.Form.Get("lastname"),
|
||||
ActivationKey: r.Form.Get("activationKey"),
|
||||
Revised: time.Now().UTC(),
|
||||
}
|
||||
|
||||
if details.Company == "" ||
|
||||
|
@ -108,15 +112,16 @@ func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// The result of completing the onboarding process.
|
||||
type onboardRequest struct {
|
||||
URL string
|
||||
Company string
|
||||
CompanyLong string
|
||||
Message string
|
||||
Email string
|
||||
Password string
|
||||
Firstname string
|
||||
Lastname string
|
||||
Revised time.Time
|
||||
URL string
|
||||
Company string
|
||||
CompanyLong string
|
||||
Message string
|
||||
Email string
|
||||
Password string
|
||||
Firstname string
|
||||
Lastname string
|
||||
ActivationKey string
|
||||
Revised time.Time
|
||||
}
|
||||
|
||||
// setupAccount prepares the database for a newly onboard customer.
|
||||
|
@ -132,10 +137,14 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er
|
|||
salt := secrets.GenerateSalt()
|
||||
password := secrets.GeneratePassword(completion.Password, salt)
|
||||
|
||||
// Process activation key if we have one.
|
||||
activationKey := processActivationKey(rt, completion)
|
||||
|
||||
// Allocate organization to the user.
|
||||
orgID := uniqueid.Generate()
|
||||
_, err = tx.Exec(RebindParams("INSERT INTO dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial) VALUES (?, ?, ?, ?, ?, ?, ?)", rt.StoreProvider.Type()),
|
||||
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial)
|
||||
_, err = tx.Exec(RebindParams("INSERT INTO dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial, c_sub) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
rt.StoreProvider.Type()),
|
||||
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial, activationKey)
|
||||
if err != nil {
|
||||
rt.Log.Error("INSERT INTO dmz_org failed", err)
|
||||
tx.Rollback()
|
||||
|
@ -243,3 +252,30 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
func processActivationKey(rt *env.Runtime, or onboardRequest) (key string) {
|
||||
key = "{}"
|
||||
if len(or.ActivationKey) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
j := domain.SubscriptionData{}
|
||||
x := domain.SubscriptionXML{Key: "", Signature: ""}
|
||||
|
||||
err1 := xml.Unmarshal([]byte(or.ActivationKey), &x)
|
||||
if err1 == nil {
|
||||
j.Key = x.Key
|
||||
j.Signature = x.Signature
|
||||
} else {
|
||||
rt.Log.Error("failed to XML unmarshal subscription XML", err1)
|
||||
}
|
||||
|
||||
d, err2 := json.Marshal(j)
|
||||
if err2 == nil {
|
||||
key = string(d)
|
||||
} else {
|
||||
rt.Log.Error("failed to JSON marshal subscription XML", err2)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
34
gui/app/components/setup/first-run.js
Normal file
34
gui/app/components/setup/first-run.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import Modals from '../../mixins/modal';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend(Modals, {
|
||||
localStorage: service(),
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
let firstRun = this.get('localStorage').isFirstRun();
|
||||
|
||||
if (firstRun) {
|
||||
this.modalOpen('#first-run-modal', {'show': true});
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
onCloseModal() {
|
||||
this.modalClose('#first-run-modal');
|
||||
}
|
||||
}
|
||||
});
|
|
@ -7,6 +7,7 @@
|
|||
<title>Documize</title>
|
||||
<meta property="dbname" content="{{.DBname}}" />
|
||||
<meta property="dbhash" content="{{.DBhash}}" />
|
||||
<meta property="edition" content="{{.Edition}}" />
|
||||
<meta name="author" content="Documize" />
|
||||
<meta name="description" content="Documize">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
|
|
|
@ -16,8 +16,12 @@ export default Route.extend({
|
|||
session: service(),
|
||||
localStorage: service(),
|
||||
|
||||
beforeModel() {
|
||||
beforeModel(transition) {
|
||||
this.get('localStorage').clearAll();
|
||||
|
||||
if (!_.isUndefined(transition.to.queryParams.fr)) {
|
||||
this.get('localStorage').setFirstRun();
|
||||
}
|
||||
},
|
||||
|
||||
model({ token }) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="sso-box">
|
||||
<p>Signing in...</p>
|
||||
<img src="/assets/img/busy-gray.gif">
|
||||
<img src="/assets/img/busy-gray.gif" alt="busy">
|
||||
</div>
|
||||
|
|
|
@ -23,10 +23,10 @@ export default Controller.extend({
|
|||
data: this.model,
|
||||
dataType: "text",
|
||||
}).then(() => {
|
||||
let dom = ""; // supports http://localhost:5001 installations (which is the default for all self-installs)
|
||||
var credentials = Encoding.Base64.encode(dom + ":" + this.model.email + ":" + this.model.password);
|
||||
window.location.href = "/auth/sso/" + encodeURIComponent(credentials);
|
||||
}).catch((error) => { // eslint-disable-line no-unused-vars
|
||||
let dom = ""; // supports http://localhost:5001 installs (which is the default for all self-installs)
|
||||
let credentials = Encoding.Base64.encode(dom + ":" + this.model.email + ":" + this.model.password);
|
||||
window.location.href = "/auth/sso/" + encodeURIComponent(credentials) + '?fr=1';
|
||||
}).catch((/*error*/) => {
|
||||
// TODO notify user of the error within the GUI
|
||||
});
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ export default Route.extend({
|
|||
firstname: "",
|
||||
lastname: "",
|
||||
email: "",
|
||||
password: pwd
|
||||
password: pwd,
|
||||
activationKey: '',
|
||||
edition: document.head.querySelector("[property=edition]").content
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -59,10 +59,12 @@ export default Service.extend({
|
|||
|
||||
let isInSetupMode = dbhash && dbhash !== "{{.DBhash}}";
|
||||
if (isInSetupMode) {
|
||||
let edition = document.head.querySelector("[property=edition]");
|
||||
this.setProperties({
|
||||
title: htmlSafe("Documize Setup"),
|
||||
allowAnonymousAccess: true,
|
||||
setupMode: true
|
||||
setupMode: true,
|
||||
edition: !_.isNull(edition) ? edition : 'Community'
|
||||
});
|
||||
|
||||
this.get('localStorage').clearAll();
|
||||
|
|
|
@ -12,22 +12,23 @@
|
|||
import Service from '@ember/service';
|
||||
|
||||
export default Service.extend({
|
||||
storeSessionItem: function (key, data) {
|
||||
localStorage[key] = data;
|
||||
},
|
||||
|
||||
getSessionItem: function (key) {
|
||||
return localStorage[key];
|
||||
},
|
||||
|
||||
clearSessionItem: function (key) {
|
||||
delete localStorage[key];
|
||||
},
|
||||
|
||||
// Remove all items from storage.
|
||||
clearAll() {
|
||||
localStorage.clear();
|
||||
},
|
||||
|
||||
// Generic session item CRUD methods.
|
||||
storeSessionItem: function (key, data) {
|
||||
localStorage[key] = data;
|
||||
},
|
||||
getSessionItem: function (key) {
|
||||
return localStorage[key];
|
||||
},
|
||||
clearSessionItem: function (key) {
|
||||
delete localStorage[key];
|
||||
},
|
||||
|
||||
// Per document expand/collapse state.
|
||||
getDocSectionHide(docId) {
|
||||
let state = localStorage[`doc-hide-${docId}`];
|
||||
if (_.isUndefined(state) || _.isEmpty(state)) {
|
||||
|
@ -36,7 +37,6 @@ export default Service.extend({
|
|||
|
||||
return _.split(state, '|');
|
||||
},
|
||||
|
||||
setDocSectionHide(docId, state) {
|
||||
let key = `doc-hide-${docId}`;
|
||||
|
||||
|
@ -46,4 +46,15 @@ export default Service.extend({
|
|||
localStorage[key] = _.join(state, '|');
|
||||
}
|
||||
},
|
||||
|
||||
// First run wizard.
|
||||
setFirstRun() {
|
||||
localStorage['firstRun'] = true;
|
||||
},
|
||||
isFirstRun() {
|
||||
return !_.isUndefined(localStorage['firstRun']);
|
||||
},
|
||||
unsetFirstRun() {
|
||||
delete localStorage['firstRun'];
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="installer">
|
||||
<img src="/assets/img/setup/logo-purple.png" srcset="/assets/img/setup/logo-purple@2x.png" alt="Documize Setup" style="width: 250px; height: 76px;">
|
||||
<Ui::UiSpacer @size="300" />
|
||||
<h1 class="color-theme-700">Installation Guide</h1>
|
||||
<h1 class="color-theme-700">Setup</h1>
|
||||
<p class="color-gray-800">
|
||||
Review the <a href="https://docs.documize.com/s/VzO9ZqMOCgABGyfW/installation-guides/d/V16L08ucxwABhZF6/installation-guide">installation instructions</a>
|
||||
and recommended <a href="https://docs.documize.com/s/VzO9ZqMOCgABGyfW/installation-guides/d/V2KuM8ICcQABagM5/mysql-specific-database-tuning">database tuning guide</a>
|
||||
|
@ -11,27 +11,33 @@
|
|||
<form {{action "save" on="submit"}}>
|
||||
<div class="form-group">
|
||||
<label>Site name</label>
|
||||
{{focus-input id="siteTitle" type="text" value=model.title class=(if hasEmptyTitleError "form-control is-invalid" "form-control")}}
|
||||
{{focus-input id="setup-title" type="text" value=model.title class=(if hasTitleError "form-control is-invalid" "form-control")}}
|
||||
<small class="form-text text-muted">Usually your company or team name</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="adminFirstname">Firstname</label>
|
||||
{{input id="adminFirstname" type="text" value=model.firstname class=(if hasEmptyFirstnameError "form-control is-invalid" "form-control")}}
|
||||
<label for="setup-firstname">Firstname</label>
|
||||
{{input id="setup-firstname" type="text" value=model.firstname class=(if hasFirstnameError "form-control is-invalid" "form-control")}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="adminLastname">Lastname</label>
|
||||
{{input id="adminLastname" type="text" value=model.lastname class=(if hasEmptyLastnameError "form-control is-invalid" "form-control")}}
|
||||
<label for="setup-lastname">Lastname</label>
|
||||
{{input id="setup-lastname" type="text" value=model.lastname class=(if hasLastnameError "form-control is-invalid" "form-control")}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="adminEmail">Email</label>
|
||||
{{input id="adminEmail" type="email" value=model.email class=(if hasEmptyEmailError "form-control is-invalid" "form-control")}}
|
||||
<small class="form-text text-muted">No spam. Ever.</small>
|
||||
<label for="setup-email">Email</label>
|
||||
{{input id="setup-email" type="email" value=model.email class=(if hasEmailError "form-control is-invalid" "form-control")}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="adminPassword">Password</label>
|
||||
{{input id="adminPassword" type="password" value=model.password class=(if hasEmptyPasswordError "form-control is-invalid" "form-control")}}
|
||||
<label for="new-password">Password</label>
|
||||
{{input id="new-password" type="password" value=model.password class=(if hasPasswordError "form-control is-invalid" "form-control")}}
|
||||
<small class="form-text text-muted">Pick something strong and unique that you don't use anywhere else</small>
|
||||
</div>
|
||||
{{#if (eq model.edition constants.Product.EnterpriseEdition)}}
|
||||
<div class="form-group">
|
||||
<label for="activation-key">Activation Key</label>
|
||||
{{textarea id="activation-key" value=model.activationKey rows="5" class=(if hasKeyError "form-control is-invalid" "form-control")}}
|
||||
<small class="form-text text-muted">You can get it from <a href="https://www.documize.com/downloads" target="_blank">https://www.documize.com/downloads</a></small>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{ui/ui-button submit=true color=constants.Color.Green light=true label=buttonLabel onClick=(action "save")}}
|
||||
</form>
|
||||
|
||||
|
|
13
gui/app/templates/components/setup/first-run.hbs
Normal file
13
gui/app/templates/components/setup/first-run.hbs
Normal file
|
@ -0,0 +1,13 @@
|
|||
<div id="first-run-modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">Getting Started</div>
|
||||
<div class="modal-body">
|
||||
<p>dfdfdf</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{ui/ui-button color=constants.Color.Yellow light=true label="Got it!" dismiss=true}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue