mirror of
https://github.com/outbackdingo/labca.git
synced 2026-01-27 18:19:33 +00:00
Merge branch 'release/0.9.0'
* release/0.9.0: Mouseover title with actual datetime when last checked for updates Bump boulder version to release-2020-04-13 Fix version display now that we use version prefix v Check for new versions and upgrade from webgui. closes #1 Reduce the purgeInterval
This commit is contained in:
@@ -199,6 +199,9 @@ case $txt in
|
||||
"server-shutdown")
|
||||
halt
|
||||
;;
|
||||
"version-update")
|
||||
/home/labca/labca/install &>>$LOGFILE
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command '$txt'. ERROR!"
|
||||
exit 1
|
||||
@@ -206,8 +209,3 @@ case $txt in
|
||||
esac
|
||||
|
||||
echo "ok"
|
||||
|
||||
|
||||
# TODO:
|
||||
# upgrade the labca stuff
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ index 444beae43..e9bd228ef 100644
|
||||
+++ b/test/config/expiration-mailer.json
|
||||
@@ -12,6 +12,11 @@
|
||||
"nagCheckInterval": "24h",
|
||||
"emailTemplate": "labca/example-expiration-template",
|
||||
"emailTemplate": "test/example-expiration-template",
|
||||
"debugAddr": ":8008",
|
||||
+ "dnsTries": 3,
|
||||
+ "dnsResolvers": [
|
||||
@@ -12,8 +12,8 @@ index 444beae43..e9bd228ef 100644
|
||||
+ "127.0.0.1:8054"
|
||||
+ ],
|
||||
"tls": {
|
||||
"caCertFile": "labca/grpc-creds/minica.pem",
|
||||
"certFile": "labca/grpc-creds/expiration-mailer.boulder/cert.pem",
|
||||
"caCertFile": "test/grpc-creds/minica.pem",
|
||||
"certFile": "test/grpc-creds/expiration-mailer.boulder/cert.pem",
|
||||
@@ -28,5 +33,10 @@
|
||||
"syslog": {
|
||||
"stdoutlevel": 6,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/docker-compose.yml b/docker-compose.yml
|
||||
index f3279eeab..76573dabe 100644
|
||||
index e34704a4d..46365bdcf 100644
|
||||
--- a/docker-compose.yml
|
||||
+++ b/docker-compose.yml
|
||||
@@ -6,7 +6,7 @@ services:
|
||||
@@ -34,7 +34,7 @@ index f3279eeab..76573dabe 100644
|
||||
+ restart: always
|
||||
bhsm:
|
||||
# To minimize fetching this should be the same version used above
|
||||
image: letsencrypt/boulder-tools-go${TRAVIS_GO_VERSION:-1.13.2}:2020-01-07
|
||||
image: letsencrypt/boulder-tools-go${TRAVIS_GO_VERSION:-1.13.2}:2020-04-08
|
||||
@@ -68,8 +75,16 @@ services:
|
||||
bluenet:
|
||||
aliases:
|
||||
@@ -64,7 +64,7 @@ index f3279eeab..76573dabe 100644
|
||||
+ max-file: "5"
|
||||
+ restart: always
|
||||
+ labca:
|
||||
image: letsencrypt/boulder-tools-go${TRAVIS_GO_VERSION:-1.13.2}:2020-01-07
|
||||
image: letsencrypt/boulder-tools-go${TRAVIS_GO_VERSION:-1.13.2}:2020-04-08
|
||||
- environment:
|
||||
- GO111MODULE: "on"
|
||||
- GOFLAGS: "-mod=vendor"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/cmd/expiration-mailer/main.go b/cmd/expiration-mailer/main.go
|
||||
index 49ce1a265..9d47457b9 100644
|
||||
index 6d31a7033..c2ad80495 100644
|
||||
--- a/cmd/expiration-mailer/main.go
|
||||
+++ b/cmd/expiration-mailer/main.go
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
@@ -19,7 +19,7 @@ index 49ce1a265..9d47457b9 100644
|
||||
)
|
||||
|
||||
type regStore interface {
|
||||
@@ -384,6 +385,9 @@ type config struct {
|
||||
@@ -383,6 +384,9 @@ type config struct {
|
||||
TLS cmd.TLSConfig
|
||||
SAService *cmd.GRPCClientConfig
|
||||
|
||||
@@ -29,7 +29,7 @@ index 49ce1a265..9d47457b9 100644
|
||||
// Path to a file containing a list of trusted root certificates for use
|
||||
// during the SMTP connection (as opposed to the gRPC connections).
|
||||
SMTPTrustedRootFile string
|
||||
@@ -392,6 +396,12 @@ type config struct {
|
||||
@@ -391,6 +395,12 @@ type config struct {
|
||||
}
|
||||
|
||||
Syslog cmd.SyslogConfig
|
||||
@@ -42,7 +42,7 @@ index 49ce1a265..9d47457b9 100644
|
||||
}
|
||||
|
||||
func initStats(stats prometheus.Registerer) mailerStats {
|
||||
@@ -495,6 +505,30 @@ func main() {
|
||||
@@ -494,6 +504,30 @@ func main() {
|
||||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
|
||||
sac := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
|
||||
|
||||
@@ -73,7 +73,7 @@ index 49ce1a265..9d47457b9 100644
|
||||
var smtpRoots *x509.CertPool
|
||||
if c.Mailer.SMTPTrustedRootFile != "" {
|
||||
pem, err := ioutil.ReadFile(c.Mailer.SMTPTrustedRootFile)
|
||||
@@ -530,6 +564,7 @@ func main() {
|
||||
@@ -529,6 +563,7 @@ func main() {
|
||||
c.Mailer.Username,
|
||||
smtpPassword,
|
||||
smtpRoots,
|
||||
|
||||
@@ -44,6 +44,7 @@ sed -i -e "s/\"server\": \".*\"/\"server\": \"$PKI_EMAIL_SERVER\"/" config/expir
|
||||
sed -i -e "s/\"port\": \".*\"/\"port\": \"$PKI_EMAIL_PORT\"/" config/expiration-mailer.json
|
||||
sed -i -e "s/\"username\": \".*\"/\"username\": \"$PKI_EMAIL_USER\"/" config/expiration-mailer.json
|
||||
sed -i -e "s/\"from\": \".*\"/\"from\": \"$PKI_EMAIL_FROM\"/" config/expiration-mailer.json
|
||||
sed -i -e "s/\"purgeInterval\": \".*\"/\"purgeInterval\": \"1s\"/" config/akamai-purger.json
|
||||
|
||||
if [ "$PKI_EMAIL_PASS" != "" ]; then
|
||||
sed -i -e "s/.*/$PKI_EMAIL_PASS/" secrets/smtp_password
|
||||
|
||||
107
gui/main.go
107
gui/main.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
@@ -11,7 +12,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/biz/templates"
|
||||
"github.com/dustin/go-humanize"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/securecookie"
|
||||
"github.com/gorilla/sessions"
|
||||
@@ -39,20 +42,23 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
writeWait = 10 * time.Second
|
||||
pongWait = 60 * time.Second
|
||||
pingPeriod = (pongWait * 9) / 10
|
||||
writeWait = 10 * time.Second
|
||||
pongWait = 60 * time.Second
|
||||
pingPeriod = (pongWait * 9) / 10
|
||||
updateInterval = 24 * time.Hour
|
||||
)
|
||||
|
||||
var (
|
||||
appSession *sessions.Session
|
||||
restartSecret string
|
||||
sessionStore *sessions.CookieStore
|
||||
tmpls *templates.Templates
|
||||
version string
|
||||
dbConn string
|
||||
dbType string
|
||||
isDev bool
|
||||
appSession *sessions.Session
|
||||
restartSecret string
|
||||
sessionStore *sessions.CookieStore
|
||||
tmpls *templates.Templates
|
||||
version string
|
||||
dbConn string
|
||||
dbType string
|
||||
isDev bool
|
||||
updateAvailable bool
|
||||
updateChecked time.Time
|
||||
|
||||
upgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
@@ -232,6 +238,43 @@ func errorHandler(w http.ResponseWriter, r *http.Request, err error, status int)
|
||||
}
|
||||
}
|
||||
|
||||
func checkUpdates(forced bool) ([]string, []string) {
|
||||
var versions []string
|
||||
var descriptions []string
|
||||
|
||||
if forced || updateChecked.Add(updateInterval).Before(time.Now()) {
|
||||
latest := ""
|
||||
newer := true
|
||||
|
||||
client := github.NewClient(nil)
|
||||
|
||||
if releases, _, err := client.Repositories.ListReleases(context.Background(), "hakwerk", "labca", nil); err == nil {
|
||||
for i := 0; i < len(releases); i++ {
|
||||
release := releases[i]
|
||||
if !*release.Draft {
|
||||
if !*release.Prerelease || isDev {
|
||||
if latest == "" {
|
||||
latest = *release.Name
|
||||
}
|
||||
if *release.Name == version {
|
||||
newer = false
|
||||
}
|
||||
if newer {
|
||||
versions = append(versions, *release.Name)
|
||||
descriptions = append(descriptions, *release.Body)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateChecked = time.Now()
|
||||
updateAvailable = (len(releases) > 0) && (latest != version)
|
||||
}
|
||||
}
|
||||
|
||||
return versions, descriptions
|
||||
}
|
||||
|
||||
func rootHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !viper.GetBool("config.complete") {
|
||||
http.Redirect(w, r, r.Header.Get("X-Request-Base")+"/setup", http.StatusFound)
|
||||
@@ -240,6 +283,11 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
dashboardData, err := CollectDashboardData(w, r)
|
||||
if err == nil {
|
||||
checkUpdates(false)
|
||||
dashboardData["UpdateAvailable"] = updateAvailable
|
||||
dashboardData["UpdateChecked"] = strings.Replace(updateChecked.Format("02-Jan-2006 15:04:05 MST"), "+0000", "GMT", -1)
|
||||
dashboardData["UpdateCheckedRel"] = humanize.RelTime(updateChecked, time.Now(), "", "")
|
||||
|
||||
render(w, r, "dashboard", dashboardData)
|
||||
}
|
||||
}
|
||||
@@ -798,6 +846,27 @@ func (res *Result) ManageComponents(w http.ResponseWriter, r *http.Request, acti
|
||||
}
|
||||
}
|
||||
|
||||
func _checkUpdatesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
res := struct {
|
||||
Success bool
|
||||
UpdateAvailable bool
|
||||
UpdateChecked string
|
||||
UpdateCheckedRel string
|
||||
Versions []string
|
||||
Descriptions []string
|
||||
Errors map[string]string
|
||||
}{Success: true, Errors: make(map[string]string)}
|
||||
|
||||
res.Versions, res.Descriptions = checkUpdates(true)
|
||||
res.UpdateAvailable = updateAvailable
|
||||
res.UpdateChecked = updateChecked.Format("02-Jan-2006 15:04:05 MST")
|
||||
res.UpdateChecked = strings.Replace(res.UpdateChecked, "+0000", "GMT", -1)
|
||||
res.UpdateCheckedRel = humanize.RelTime(updateChecked, time.Now(), "", "")
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
func _managePostDispatch(w http.ResponseWriter, r *http.Request, action string) bool {
|
||||
if action == "backup-restore" || action == "backup-delete" || action == "backup-now" {
|
||||
_backupHandler(w, r)
|
||||
@@ -829,6 +898,11 @@ func _managePostDispatch(w http.ResponseWriter, r *http.Request, action string)
|
||||
return true
|
||||
}
|
||||
|
||||
if action == "version-check" {
|
||||
_checkUpdatesHandler(w, r)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -858,6 +932,8 @@ func _managePost(w http.ResponseWriter, r *http.Request) {
|
||||
"update-config",
|
||||
"update-email",
|
||||
"send-email",
|
||||
"version-check",
|
||||
"version-update",
|
||||
} {
|
||||
if a == action {
|
||||
actionKnown = true
|
||||
@@ -878,7 +954,7 @@ func _managePost(w http.ResponseWriter, r *http.Request) {
|
||||
res.Message = "Command failed - see LabCA log for any details"
|
||||
}
|
||||
|
||||
if action != "server-restart" && action != "server-shutdown" {
|
||||
if action != "server-restart" && action != "server-shutdown" && action != "version-update" {
|
||||
res.ManageComponents(w, r, action)
|
||||
}
|
||||
|
||||
@@ -890,6 +966,11 @@ func _manageGet(w http.ResponseWriter, r *http.Request) {
|
||||
manageData := make(map[string]interface{})
|
||||
manageData["RequestBase"] = r.Header.Get("X-Request-Base")
|
||||
|
||||
checkUpdates(false)
|
||||
manageData["UpdateAvailable"] = updateAvailable
|
||||
manageData["UpdateChecked"] = strings.Replace(updateChecked.Format("02-Jan-2006 15:04:05 MST"), "+0000", "GMT", -1)
|
||||
manageData["UpdateCheckedRel"] = humanize.RelTime(updateChecked, time.Now(), "", "")
|
||||
|
||||
components := _parseComponents(getLog(w, r, "components"))
|
||||
for i := 0; i < len(components); i++ {
|
||||
if components[i].Name == "NGINX Webserver" {
|
||||
@@ -2292,6 +2373,8 @@ func init() {
|
||||
dbType = viper.GetString("db.type")
|
||||
|
||||
version = viper.GetString("version")
|
||||
|
||||
updateAvailable = false
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -9,6 +9,7 @@ if [ ! -e bin/labca ]; then
|
||||
go get github.com/biz/templates
|
||||
go get github.com/go-sql-driver/mysql
|
||||
go get github.com/dustin/go-humanize
|
||||
go get github.com/google/go-github/github
|
||||
go get github.com/gorilla/mux
|
||||
go get github.com/gorilla/securecookie
|
||||
go get github.com/gorilla/sessions
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 footer text-muted">
|
||||
<small>{{ if .Version }}Version {{ .Version }}{{ end }}</small>
|
||||
<small>{{ if .Version }}{{ .Version }}{{ end }}</small>
|
||||
</div>
|
||||
<div class="col-sm-6 footer text-muted text-right" id="footer">
|
||||
<small>Copyright © 2018-2020 LabCA</small>
|
||||
|
||||
@@ -127,7 +127,13 @@
|
||||
<div class="col-lg-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-fw fa-desktop"></i> System Overview
|
||||
<span class="pull-left"><i class="fa fa-fw fa-desktop"></i> System Overview</span>
|
||||
{{ if .UpdateAvailable }}
|
||||
<span class="pull-right">
|
||||
<a class="update" href="{{ .RequestBase }}/manage"><i class="fa fa-fw fa-rocket"></i> <i>update available!</i></a>
|
||||
</span>
|
||||
{{ end }}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
|
||||
@@ -43,6 +43,16 @@
|
||||
{{ range $btn := $item.Buttons }}
|
||||
<button class="btn btn-outline btn-reg {{ $btn.Class }}" type="button" id="{{ $btn.Id }}" title="{{ $btn.Title }}">{{ $btn.Label }}</button>
|
||||
{{ end }}
|
||||
{{ if eq $item.Name "LabCA Application" }}
|
||||
<br/>
|
||||
<button class="btn btn-outline btn-wide btn-warning mt5 {{ if not $.UpdateAvailable }}hidden{{ end }}" type="button" id="version-update" title="Update to latest version">Update LabCA</button>
|
||||
<br/>
|
||||
<button class="btn btn-outline btn-wide btn-success mt5" type="button" id="version-check" title="Check if there is a newer version available">Check for updates</button>
|
||||
<span id="update-checked-span">
|
||||
<br/>
|
||||
Last checked: <span id="update-last-checked" title="{{ $.UpdateChecked }}">{{ $.UpdateCheckedRel }}</span>
|
||||
</span>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
@@ -262,7 +272,7 @@
|
||||
|
||||
<span class="hidden" id="request-base">{{ .RequestBase }}</span>
|
||||
|
||||
<div class="modal fade bd-modal-lg" data-backdrop="static" data-keyboard="false" tabindex="-1">
|
||||
<div id="modal-spinner" class="modal fade bd-modal-lg" data-backdrop="static" data-keyboard="false" tabindex="-1">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content" style="width: 48px">
|
||||
<img id="manage-spinner" src="static/img/spinner.gif" height="36">
|
||||
@@ -275,6 +285,7 @@
|
||||
<script type="text/javascript" src="static/js/zxcvbn.js"></script>
|
||||
<script type="text/javascript" src="static/js/pwdux.js"></script>
|
||||
<script type="text/javascript" src="static/js/jquery.stickytabs.js"></script>
|
||||
<script type="text/javascript" src="static/js/bootstrap-dialog.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
$('.nav-tabs-sticky').stickyTabs();
|
||||
@@ -292,7 +303,13 @@
|
||||
});
|
||||
|
||||
$(".btn").click(function(evt) {
|
||||
$('.modal').modal('show');
|
||||
$('#modal-spinner').modal('show');
|
||||
if ($(evt.target).hasClass('btn-warning') || $(evt.target).hasClass('btn-danger')) {
|
||||
if (!window.confirm("Are you sure?")) {
|
||||
$('#modal-spinner').modal('hide');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$(evt.target).blur();
|
||||
$("#backup-result").hide();
|
||||
$("#export-pwd-err").hide();
|
||||
@@ -314,7 +331,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully created backup";
|
||||
@@ -327,7 +344,7 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#backup-result").removeClass("hidden").removeClass("success").show().text(err).addClass("error");
|
||||
});
|
||||
|
||||
@@ -342,7 +359,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully restored backup, restarting server now...";
|
||||
@@ -356,7 +373,7 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#backup-result").removeClass("hidden").removeClass("success").show().text(err).addClass("error");
|
||||
});
|
||||
|
||||
@@ -372,7 +389,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully removed backup file";
|
||||
@@ -384,7 +401,7 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#backup-result").removeClass("hidden").removeClass("success").show().text(err).addClass("error");
|
||||
});
|
||||
|
||||
@@ -392,10 +409,10 @@
|
||||
type = ($("#export-zip").prop('checked') ? "zip" : ($("#export-pfx").prop('checked') ? "pfx" : "none"));
|
||||
|
||||
if ($("#export-pwd").val().length < 4) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#export-pwd-err").removeClass("hidden").show().text("Password needs to be at least 4 characters!");
|
||||
} else if ($("#export-pwd").val() != $("#export-pwd2").val()) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#export-pwd2-err").removeClass("hidden").show().text("Passwords are not the same!");
|
||||
} else {
|
||||
var req = new XMLHttpRequest();
|
||||
@@ -404,7 +421,7 @@
|
||||
req.responseType = "blob";
|
||||
|
||||
req.onload = function (event) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
var blob = req.response;
|
||||
var fileName = null;
|
||||
@@ -430,7 +447,7 @@
|
||||
};
|
||||
|
||||
req.onerror = function (event) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#cert-export-err").removeClass("hidden").show().text("Oops, something went wrong...");
|
||||
};
|
||||
|
||||
@@ -451,7 +468,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully updated account.";
|
||||
@@ -479,7 +496,7 @@
|
||||
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#update-account-result").removeClass("hidden").removeClass("success").show().text(err).addClass("error");
|
||||
});
|
||||
|
||||
@@ -498,7 +515,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully updated configuration.<br/>";
|
||||
@@ -518,14 +535,14 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#update-config-result").removeClass("hidden").removeClass("success").show().html(err + "<br/>").addClass("error");
|
||||
});
|
||||
|
||||
} else if ( $(evt.target).attr("id") == "update-email") {
|
||||
form = $(evt.target).parent().parent()[0]
|
||||
if (!form.checkValidity()) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
const tmpSubmit = document.createElement('button')
|
||||
form.appendChild(tmpSubmit)
|
||||
tmpSubmit.click()
|
||||
@@ -545,7 +562,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully updated configuration.<br/>";
|
||||
@@ -563,7 +580,7 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#update-email-result").removeClass("hidden").removeClass("success").show().html(err + "<br/>").addClass("error");
|
||||
});
|
||||
}
|
||||
@@ -576,7 +593,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
var msg = "Successfully sent test email.<br/>";
|
||||
@@ -594,10 +611,63 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#send-email-result").removeClass("hidden").removeClass("success").show().html(err + "<br/>").addClass("error");
|
||||
});
|
||||
|
||||
} else if ( $(evt.target).attr("id") == "version-check") {
|
||||
$.ajax(window.location.href, {
|
||||
method: "POST",
|
||||
data: {
|
||||
action: $(evt.target).attr("id"),
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
if (data.Success) {
|
||||
if (data.UpdateAvailable) {
|
||||
$("#version-update").removeClass("hidden");
|
||||
|
||||
var notes = "<span class=\"rel-notes-title\">RELEASE NOTES</span><br/><br/>";
|
||||
jQuery.each(data.Versions, function(idx, val) {
|
||||
notes += "<span class=\"rel-notes-title\">" + val + "</span><br/>"
|
||||
notes += "<span>" + data.Descriptions[idx] + "</span><br/><br/>"
|
||||
});
|
||||
BootstrapDialog.show({
|
||||
title: 'New version available!',
|
||||
message: notes,
|
||||
buttons: [{
|
||||
label: 'OK',
|
||||
cssClass: 'btn-outline btn-success',
|
||||
action: function(dialogRef){
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
} else {
|
||||
$("#version-update").addClass("hidden")
|
||||
BootstrapDialog.show({
|
||||
title: 'No new version',
|
||||
message: 'There is currently no newer version available.',
|
||||
buttons: [{
|
||||
label: 'OK',
|
||||
cssClass: 'btn-outline btn-success',
|
||||
action: function(dialogRef){
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
$("#update-last-checked").attr("title", data.UpdateChecked)
|
||||
$("#update-last-checked").text(data.UpdateCheckedRel)
|
||||
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('#modal-spinner').modal('hide');
|
||||
});
|
||||
|
||||
} else {
|
||||
$.ajax(window.location.href, {
|
||||
method: "POST",
|
||||
@@ -606,7 +676,7 @@
|
||||
},
|
||||
})
|
||||
.done(function(data) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
|
||||
td = $(evt.target).parent().parent().find("td:eq(1)");
|
||||
$(td).attr("title", data.Timestamp);
|
||||
@@ -630,7 +700,7 @@
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
$('.modal').modal('hide');
|
||||
$('#modal-spinner').modal('hide');
|
||||
$("#cert-export-err").removeClass("hidden").show().text(err);
|
||||
});
|
||||
}
|
||||
|
||||
2
install
2
install
@@ -24,7 +24,7 @@ dockerComposeVersion="1.22.0"
|
||||
|
||||
labcaUrl="https://github.com/hakwerk/labca/"
|
||||
boulderUrl="https://github.com/letsencrypt/boulder/"
|
||||
boulderTag="release-2020-02-17"
|
||||
boulderTag="release-2020-04-13"
|
||||
|
||||
#
|
||||
# Color configuration
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/cmd/notify-mailer/main.go b/cmd/notify-mailer/main.go
|
||||
index f61f21086..87504c55b 100644
|
||||
index bb8945236..e278cdc16 100644
|
||||
--- a/cmd/notify-mailer/main.go
|
||||
+++ b/cmd/notify-mailer/main.go
|
||||
@@ -472,6 +472,7 @@ func main() {
|
||||
@@ -468,6 +468,7 @@ func main() {
|
||||
cfg.NotifyMailer.Username,
|
||||
smtpPassword,
|
||||
nil,
|
||||
|
||||
@@ -83,6 +83,10 @@ p.caption {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
@@ -126,3 +130,24 @@ p.caption {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
a.update {
|
||||
color: darkgreen;
|
||||
}
|
||||
|
||||
a.update:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.bootstrap-dialog .modal-header {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
.bootstrap-dialog.type-primary .modal-header {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.rel-notes-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
1
www/js/bootstrap-dialog.min.js
vendored
Normal file
1
www/js/bootstrap-dialog.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user