mirror of
https://github.com/cloudflare/redoctober.git
synced 2026-01-04 04:04:24 +00:00
Make red october have slices of labels, and a link generator
This commit is contained in:
35
core/core.go
35
core/core.go
@@ -118,7 +118,7 @@ type OrderRequest struct {
|
||||
Duration string
|
||||
Uses string
|
||||
Data []byte
|
||||
Label string
|
||||
Labels []string
|
||||
}
|
||||
|
||||
type OrderInfoRequest struct {
|
||||
@@ -400,17 +400,16 @@ func Delegate(jsonIn []byte) ([]byte, error) {
|
||||
|
||||
// Make sure we capture the number who have already delegated.
|
||||
for _, delegatedUser := range s.Users {
|
||||
for _, delegatedLabel := range s.Labels {
|
||||
if orderKey, found := orders.FindOrder(delegatedUser, delegatedLabel); found {
|
||||
order := orders.Orders[orderKey]
|
||||
order.AdminsDelegated = append(order.AdminsDelegated, s.Name)
|
||||
order.Delegated++
|
||||
orders.Orders[orderKey] = order
|
||||
if orderKey, found := orders.FindOrder(delegatedUser, s.Labels); found {
|
||||
order := orders.Orders[orderKey]
|
||||
order.AdminsDelegated = append(order.AdminsDelegated, s.Name)
|
||||
|
||||
// Notify the hipchat room that there was a new delegator
|
||||
orders.NotifyDelegation(s.Name, delegatedLabel, delegatedUser, orderKey, s.Time)
|
||||
order.Delegated++
|
||||
orders.Orders[orderKey] = order
|
||||
|
||||
// Notify the hipchat room that there was a new delegator
|
||||
orders.NotifyDelegation(s.Name, delegatedUser, orderKey, s.Time, s.Labels)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,11 +613,9 @@ func Decrypt(jsonIn []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Cleanup any orders that have been fulfilled and notify the room.
|
||||
for _, label := range allLabels {
|
||||
if orderKey, found := orders.FindOrder(s.Name, label); found {
|
||||
delete(orders.Orders, orderKey)
|
||||
orders.NotifyOrderFulfilled(s.Name, orderKey)
|
||||
}
|
||||
if orderKey, found := orders.FindOrder(s.Name, allLabels); found {
|
||||
delete(orders.Orders, orderKey)
|
||||
orders.NotifyOrderFulfilled(s.Name, orderKey)
|
||||
}
|
||||
return jsonResponse(out)
|
||||
}
|
||||
@@ -767,21 +764,19 @@ func Order(jsonIn []byte) (out []byte, err error) {
|
||||
cache.Refresh()
|
||||
orderNum := order.GenerateNum()
|
||||
|
||||
adminsDelegated, numDelegated := cache.DelegateStatus(o.Name, o.Label, owners)
|
||||
adminsDelegated, numDelegated := cache.DelegateStatus(o.Name, o.Labels, owners)
|
||||
duration, err := time.ParseDuration(o.Duration)
|
||||
if err != nil {
|
||||
jsonStatusError(err)
|
||||
}
|
||||
currentTime := time.Now()
|
||||
expiryTime := currentTime.Add(duration)
|
||||
ord := order.CreateOrder(o.Name,
|
||||
o.Label,
|
||||
orderNum,
|
||||
currentTime,
|
||||
expiryTime,
|
||||
duration,
|
||||
adminsDelegated,
|
||||
owners,
|
||||
o.Labels,
|
||||
numDelegated)
|
||||
orders.Orders[orderNum] = ord
|
||||
out, err = json.Marshal(ord)
|
||||
@@ -790,7 +785,7 @@ func Order(jsonIn []byte) (out []byte, err error) {
|
||||
altOwners := records.GetAltNamesFromName(orders.AlternateName, owners)
|
||||
|
||||
// Let everyone on hipchat know there is a new order.
|
||||
orders.NotifyNewOrder(o.Name, o.Duration, o.Label, o.Uses, orderNum, altOwners)
|
||||
orders.NotifyNewOrder(o.Name, o.Duration, o.Uses, orderNum, o.Labels, altOwners)
|
||||
if err != nil {
|
||||
return jsonStatusError(err)
|
||||
}
|
||||
|
||||
78
index.html
78
index.html
@@ -330,8 +330,8 @@
|
||||
<input type="password" name="Password" class="form-control" id="order-user-pass" placeholder="Password" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="order-label">Label</label>
|
||||
<input type="text" name="Label" class="form-control" id="order-user-label" placeholder="Label" required />
|
||||
<label for="order-label">Labels</label>
|
||||
<input type="text" name="Labels" class="form-control" id="order-user-label" placeholder="Labels" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="order-duration">Duration</label>
|
||||
@@ -425,6 +425,44 @@
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<section class="row">
|
||||
<div id="orderscancel" class="col-md-6">
|
||||
<h3>Order Link</h3>
|
||||
|
||||
<form id="orderlink" class="ro-orderlink" role="form" action="#" method="post">
|
||||
<div style="overflow-wrap: break-word;" class="feedback orderlink-feedback"></div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-delegator">Delegator</label>
|
||||
<input type="text" name="Name" class="form-control" id="orderlink-delegator" placeholder="User name" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-labels">Labels</label>
|
||||
<input type="text" name="labels" class="form-control" id="orderlink-labels" placeholder="Labels" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-duration">Duration</label>
|
||||
<input type="text" name="duration" class="form-control" id="orderlink-duration" placeholder="1h 5m" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-uses">Uses</label>
|
||||
<input type="text" name="uses" class="form-control" id="orderlink-uses" placeholder="5" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-ordernum">OrderNum</label>
|
||||
<input type="text" name="ordernum" class="form-control" id="orderlink-ordernum" placeholder="d34db33f..." required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-delegatefor">Delegate For</label>
|
||||
<input type="text" name="delegatefor" class="form-control" id="orderlink-delegatefor" placeholder="e.g. Alice, Bob" required />
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Create Link</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
@@ -653,6 +691,11 @@
|
||||
evt.preventDefault();
|
||||
var $form = $(evt.currentTarget),
|
||||
data = serialize($form);
|
||||
data.Labels = data.Labels.split(',');
|
||||
for(var i=0, l=data.Labels.length; i<l; i++){
|
||||
data.Labels[i] = data.Labels[i].trim();
|
||||
if (data.Labels[i] == "") { data.Labels.splice(i, 1); }
|
||||
}
|
||||
|
||||
submit( $form, {
|
||||
data : data,
|
||||
@@ -668,23 +711,25 @@
|
||||
evt.preventDefault();
|
||||
var $form = $(evt.currentTarget),
|
||||
data = serialize($form);
|
||||
|
||||
alert(1);
|
||||
submit( $form, {
|
||||
data : data,
|
||||
success : function(d){
|
||||
d = window.atob(d.Response);
|
||||
try {
|
||||
var respData = JSON.parse(d);
|
||||
var msgText = ""
|
||||
alert(msgText);
|
||||
var msgText = "";
|
||||
for (var jj in respData) {
|
||||
if (!jj || jj == "Admins")
|
||||
if (!jj)
|
||||
continue;
|
||||
if (!respData.hasOwnProperty(jj)) {
|
||||
continue;
|
||||
}
|
||||
alert(msgText);
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"</p>";
|
||||
if (typeof(respData[jj]) == "object") {
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(JSON.stringify(respData[jj]))+"</p>";
|
||||
} else {
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"</p>";
|
||||
}
|
||||
}
|
||||
$form.find('.feedback').empty().append(makeAlert({ type: 'success', message: msgText }));
|
||||
} catch (e) {
|
||||
@@ -730,6 +775,10 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
$('body').on('submit', 'form#orderlink', function(evt){
|
||||
evt.preventDefault();
|
||||
createLink();
|
||||
});
|
||||
|
||||
// Init from query string if possible.
|
||||
var queryParams = document.location.search;
|
||||
@@ -767,9 +816,20 @@
|
||||
break;
|
||||
}
|
||||
if (setValue) {
|
||||
setValue.val(value);
|
||||
setValue.val(decodeURIComponent(value));
|
||||
}
|
||||
}
|
||||
function createLink() {
|
||||
var delegator = decodeURIComponent(document.getElementById("orderlink-delegator").value);
|
||||
var delegatee = decodeURIComponent(document.getElementById("orderlink-delegatefor").value);
|
||||
var duration = decodeURIComponent(document.getElementById("orderlink-duration").value);
|
||||
var orderNum = decodeURIComponent(document.getElementById("orderlink-ordernum").value);
|
||||
var labels = decodeURIComponent(document.getElementById("orderlink-labels").value);
|
||||
var uses = decodeURIComponent(document.getElementById("orderlink-uses").value);
|
||||
|
||||
var link = "https://" + document.location.host + "?delegator="+ delegator + "&delegatee="+ delegatee + "&label=" + labels + "&ordernum=" + orderNum + "&uses=" + uses + "&duration="+ duration;
|
||||
$('.orderlink-feedback').empty().append(makeAlert({ type: 'success', message: '<p>'+htmlspecialchars(link)+'</p>' }) );
|
||||
}
|
||||
function htmlspecialchars(s) {
|
||||
if (!isNaN(s)) {
|
||||
return s;
|
||||
|
||||
@@ -309,7 +309,7 @@ func (cache *Cache) DecryptShares(in [][]byte, name, user string, labels []strin
|
||||
|
||||
// DelegateStatus will return a list of admins who have delegated to a particular user, for a particular label.
|
||||
// This is useful information to have when determining the status of an order and conveying order progress.
|
||||
func (cache *Cache) DelegateStatus(name string, label string, admins []string) (adminsDelegated []string, hasDelegated int) {
|
||||
func (cache *Cache) DelegateStatus(name string, labels, admins []string) (adminsDelegated []string, hasDelegated int) {
|
||||
// Iterate over the admins of the ciphertext to look for users
|
||||
// who have already delegated the label to the delegatee.
|
||||
for _, admin := range admins {
|
||||
@@ -317,23 +317,22 @@ func (cache *Cache) DelegateStatus(name string, label string, admins []string) (
|
||||
if di.Name != admin {
|
||||
continue
|
||||
}
|
||||
labelFound := false
|
||||
nameFound := false
|
||||
for _, user := range use.Users {
|
||||
if user == name {
|
||||
nameFound = true
|
||||
}
|
||||
}
|
||||
for _, l := range use.Labels {
|
||||
if l == label {
|
||||
labelFound = true
|
||||
for _, ol := range use.Labels {
|
||||
for _, il := range labels {
|
||||
if ol == il {
|
||||
if nameFound {
|
||||
adminsDelegated = append(adminsDelegated, admin)
|
||||
hasDelegated++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if labelFound && nameFound {
|
||||
adminsDelegated = append(adminsDelegated, admin)
|
||||
hasDelegated++
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -22,12 +22,11 @@ type Order struct {
|
||||
Num string
|
||||
|
||||
TimeRequested time.Time
|
||||
ExpiryTime time.Time
|
||||
DurationRequested time.Duration
|
||||
Delegated int
|
||||
AdminsDelegated []string
|
||||
Admins []string
|
||||
Label string
|
||||
Labels []string
|
||||
}
|
||||
|
||||
type OrderIndex struct {
|
||||
@@ -47,12 +46,11 @@ type Orderer struct {
|
||||
AlternateName string
|
||||
}
|
||||
|
||||
func CreateOrder(name string, labels string, orderNum string, time time.Time, expiryTime time.Time, duration time.Duration, adminsDelegated, contacts []string, numDelegated int) (ord Order) {
|
||||
func CreateOrder(name, orderNum string, time time.Time, duration time.Duration, adminsDelegated, contacts, labels []string, numDelegated int) (ord Order) {
|
||||
ord.Name = name
|
||||
ord.Num = orderNum
|
||||
ord.Label = labels
|
||||
ord.Labels = labels
|
||||
ord.TimeRequested = time
|
||||
ord.ExpiryTime = expiryTime
|
||||
ord.DurationRequested = duration
|
||||
ord.AdminsDelegated = adminsDelegated
|
||||
ord.Admins = contacts
|
||||
@@ -79,13 +77,23 @@ func NewOrderer(hipchatClient hipchat.HipchatClient) (o Orderer) {
|
||||
func notify(o *Orderer, msg, color string) {
|
||||
o.Hipchat.Notify(msg, color)
|
||||
}
|
||||
func (o *Orderer) NotifyNewOrder(name, duration, label, uses, orderNum string, owners map[string]string) {
|
||||
n := fmt.Sprintf(NewOrder, name, label, uses, duration)
|
||||
func (o *Orderer) NotifyNewOrder(name, duration, uses, orderNum string, labels []string, owners map[string]string) {
|
||||
labelList := ""
|
||||
for i, label := range labels {
|
||||
if i == 0 {
|
||||
labelList += label
|
||||
} else {
|
||||
// Never include spaces in something go URI encodes. Go will
|
||||
// add a + to the string, instead of a %20
|
||||
labelList += "," + label
|
||||
}
|
||||
}
|
||||
n := fmt.Sprintf(NewOrder, name, labelList, uses, duration)
|
||||
notify(o, n, hipchat.RedBackground)
|
||||
for owner, hipchatName := range owners {
|
||||
queryParams := url.Values{
|
||||
"delegator": {owner},
|
||||
"label": {label},
|
||||
"label": {labelList},
|
||||
"duration": {duration},
|
||||
"uses": {uses},
|
||||
"ordernum": {orderNum},
|
||||
@@ -95,8 +103,16 @@ func (o *Orderer) NotifyNewOrder(name, duration, label, uses, orderNum string, o
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Orderer) NotifyDelegation(delegator, label, delegatee, orderNum, duration string) {
|
||||
n := fmt.Sprintf(NewDelegation, delegator, label, delegatee, orderNum, duration)
|
||||
func (o *Orderer) NotifyDelegation(delegator, delegatee, orderNum, duration string, labels []string) {
|
||||
labelList := ""
|
||||
for i, label := range labels {
|
||||
if i == 0 {
|
||||
labelList += label
|
||||
} else {
|
||||
labelList += ", " + label
|
||||
}
|
||||
}
|
||||
n := fmt.Sprintf(NewDelegation, delegator, labelList, delegatee, orderNum, duration)
|
||||
notify(o, n, hipchat.YellowBackground)
|
||||
}
|
||||
func (o *Orderer) NotifyOrderFulfilled(name, orderNum string) {
|
||||
@@ -104,15 +120,24 @@ func (o *Orderer) NotifyOrderFulfilled(name, orderNum string) {
|
||||
notify(o, n, hipchat.PurpleBackground)
|
||||
}
|
||||
|
||||
func (o *Orderer) FindOrder(name, label string) (string, bool) {
|
||||
func (o *Orderer) FindOrder(name string, labels []string) (string, bool) {
|
||||
for key, order := range o.Orders {
|
||||
if name != order.Name {
|
||||
continue
|
||||
}
|
||||
if label != order.Label {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, ol := range order.Labels {
|
||||
foundLabel := false
|
||||
for _, il := range labels {
|
||||
if il == ol {
|
||||
foundLabel = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !foundLabel {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
return key, true
|
||||
}
|
||||
return "", false
|
||||
|
||||
@@ -204,9 +204,9 @@ const usage = `Usage:
|
||||
redoctober -static <path> -vaultpath <path> -addr <addr> -certs <path1>[,<path2>,...] -keys <path1>[,<path2>,...] [-ca <path>]
|
||||
|
||||
single-cert example:
|
||||
redoctober -vaultpath diskrecord.json -addr localhost:8080 -certs cert.pem -keys cert.key
|
||||
redoctober -vaultpath diskrecord.json -addr localhost:8081 -certs cert.pem -keys cert.key
|
||||
multi-cert example:
|
||||
redoctober -vaultpath diskrecord.json -addr localhost:8080 -certs cert1.pem,cert2.pem -keys cert1.key,cert2.key
|
||||
redoctober -vaultpath diskrecord.json -addr localhost:8081 -certs cert1.pem,cert2.pem -keys cert1.key,cert2.key
|
||||
`
|
||||
|
||||
func main() {
|
||||
@@ -219,7 +219,7 @@ func main() {
|
||||
|
||||
var staticPath = flag.String("static", "", "Path to override built-in index.html")
|
||||
var vaultPath = flag.String("vaultpath", "diskrecord.json", "Path to the the disk vault")
|
||||
var addr = flag.String("addr", "localhost:8080", "Server and port separated by :")
|
||||
var addr = flag.String("addr", "localhost:8081", "Server and port separated by :")
|
||||
var useSystemdSocket = flag.Bool("systemdfds", false, "Use systemd socket activation to listen on a file. Useful for binding privileged sockets.")
|
||||
var certsPathString = flag.String("certs", "", "Path(s) of TLS certificate in PEM format, comma-separated")
|
||||
var keysPathString = flag.String("keys", "", "Path(s) of TLS private key in PEM format, comma-separated, must me in the same order as the certs")
|
||||
@@ -227,7 +227,7 @@ func main() {
|
||||
var hcKey = flag.String("hckey", "", "Hipchat API Key")
|
||||
var hcRoom = flag.String("hcroom", "", "Hipchat Room Id")
|
||||
var hcHost = flag.String("hchost", "", "Hipchat Url Base (ex: hipchat.com)")
|
||||
var roHost = flag.String("rohost", "", "RedOctober Url Base (ex: localhost:8080)")
|
||||
var roHost = flag.String("rohost", "", "RedOctober Url Base (ex: localhost:8081)")
|
||||
flag.Parse()
|
||||
|
||||
if *vaultPath == "" || *certsPathString == "" || *keysPathString == "" || (*addr == "" && *useSystemdSocket == false) {
|
||||
@@ -612,8 +612,8 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
<input type="password" name="Password" class="form-control" id="order-user-pass" placeholder="Password" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="order-label">Label</label>
|
||||
<input type="text" name="Label" class="form-control" id="order-user-label" placeholder="Label" required />
|
||||
<label for="order-label">Labels</label>
|
||||
<input type="text" name="Labels" class="form-control" id="order-user-label" placeholder="Labels" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="order-duration">Duration</label>
|
||||
@@ -707,6 +707,44 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<section class="row">
|
||||
<div id="orderscancel" class="col-md-6">
|
||||
<h3>Order Link</h3>
|
||||
|
||||
<form id="orderlink" class="ro-orderlink" role="form" action="#" method="post">
|
||||
<div style="overflow-wrap: break-word;" class="feedback orderlink-feedback"></div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-delegator">Delegator</label>
|
||||
<input type="text" name="Name" class="form-control" id="orderlink-delegator" placeholder="User name" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-labels">Labels</label>
|
||||
<input type="text" name="labels" class="form-control" id="orderlink-labels" placeholder="Labels" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-duration">Duration</label>
|
||||
<input type="text" name="duration" class="form-control" id="orderlink-duration" placeholder="1h 5m" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-uses">Uses</label>
|
||||
<input type="text" name="uses" class="form-control" id="orderlink-uses" placeholder="5" required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-ordernum">OrderNum</label>
|
||||
<input type="text" name="ordernum" class="form-control" id="orderlink-ordernum" placeholder="d34db33f..." required />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="orderlink-delegatefor">Delegate For</label>
|
||||
<input type="text" name="delegatefor" class="form-control" id="orderlink-delegatefor" placeholder="e.g. Alice, Bob" required />
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Create Link</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
@@ -935,6 +973,11 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
evt.preventDefault();
|
||||
var $form = $(evt.currentTarget),
|
||||
data = serialize($form);
|
||||
data.Labels = data.Labels.split(',');
|
||||
for(var i=0, l=data.Labels.length; i<l; i++){
|
||||
data.Labels[i] = data.Labels[i].trim();
|
||||
if (data.Labels[i] == "") { data.Labels.splice(i, 1); }
|
||||
}
|
||||
|
||||
submit( $form, {
|
||||
data : data,
|
||||
@@ -950,23 +993,25 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
evt.preventDefault();
|
||||
var $form = $(evt.currentTarget),
|
||||
data = serialize($form);
|
||||
|
||||
alert(1);
|
||||
submit( $form, {
|
||||
data : data,
|
||||
success : function(d){
|
||||
d = window.atob(d.Response);
|
||||
try {
|
||||
var respData = JSON.parse(d);
|
||||
var msgText = ""
|
||||
alert(msgText);
|
||||
var msgText = "";
|
||||
for (var jj in respData) {
|
||||
if (!jj || jj == "Admins")
|
||||
if (!jj)
|
||||
continue;
|
||||
if (!respData.hasOwnProperty(jj)) {
|
||||
continue;
|
||||
}
|
||||
alert(msgText);
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"</p>";
|
||||
if (typeof(respData[jj]) == "object") {
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(JSON.stringify(respData[jj]))+"</p>";
|
||||
} else {
|
||||
msgText += "<p>"+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"</p>";
|
||||
}
|
||||
}
|
||||
$form.find('.feedback').empty().append(makeAlert({ type: 'success', message: msgText }));
|
||||
} catch (e) {
|
||||
@@ -1012,6 +1057,10 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
}
|
||||
});
|
||||
});
|
||||
$('body').on('submit', 'form#orderlink', function(evt){
|
||||
evt.preventDefault();
|
||||
createLink();
|
||||
});
|
||||
|
||||
// Init from query string if possible.
|
||||
var queryParams = document.location.search;
|
||||
@@ -1049,9 +1098,20 @@ var indexHtml = []byte(`<!DOCTYPE html>
|
||||
break;
|
||||
}
|
||||
if (setValue) {
|
||||
setValue.val(value);
|
||||
setValue.val(decodeURIComponent(value));
|
||||
}
|
||||
}
|
||||
function createLink() {
|
||||
var delegator = decodeURIComponent(document.getElementById("orderlink-delegator").value);
|
||||
var delegatee = decodeURIComponent(document.getElementById("orderlink-delegatefor").value);
|
||||
var duration = decodeURIComponent(document.getElementById("orderlink-duration").value);
|
||||
var orderNum = decodeURIComponent(document.getElementById("orderlink-ordernum").value);
|
||||
var labels = decodeURIComponent(document.getElementById("orderlink-labels").value);
|
||||
var uses = decodeURIComponent(document.getElementById("orderlink-uses").value);
|
||||
|
||||
var link = "https://" + document.location.host + "?delegator="+ delegator + "&delegatee="+ delegatee + "&label=" + labels + "&ordernum=" + orderNum + "&uses=" + uses + "&duration="+ duration;
|
||||
$('.orderlink-feedback').empty().append(makeAlert({ type: 'success', message: '<p>'+htmlspecialchars(link)+'</p>' }) );
|
||||
}
|
||||
function htmlspecialchars(s) {
|
||||
if (!isNaN(s)) {
|
||||
return s;
|
||||
|
||||
Reference in New Issue
Block a user