mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Improvements for certificates table, adds expansion object to certificates
This commit is contained in:
parent
6c76c041c4
commit
456c59c746
@ -26,7 +26,7 @@ func GetCertificates() func(http.ResponseWriter, *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
certificates, err := certificate.List(pageInfo, middleware.GetFiltersFromContext(r))
|
certificates, err := certificate.List(pageInfo, middleware.GetFiltersFromContext(r), getExpandFromContext(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
||||||
} else {
|
} else {
|
||||||
@ -46,11 +46,16 @@ func GetCertificate() func(http.ResponseWriter, *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := certificate.GetByID(certificateID)
|
item, err := certificate.GetByID(certificateID)
|
||||||
if err != nil {
|
switch err {
|
||||||
|
case sql.ErrNoRows:
|
||||||
|
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
||||||
|
case nil:
|
||||||
|
// nolint: errcheck,gosec
|
||||||
|
item.Expand(getExpandFromContext(r))
|
||||||
|
h.ResultResponseJSON(w, r, http.StatusOK, item)
|
||||||
|
default:
|
||||||
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
||||||
} else {
|
|
||||||
h.ResultResponseJSON(w, r, http.StatusOK, cert)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func Update(certificate *Model) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List will return a list of certificates
|
// List will return a list of certificates
|
||||||
func List(pageInfo model.PageInfo, filters []model.Filter) (ListResponse, error) {
|
func List(pageInfo model.PageInfo, filters []model.Filter, expand []string) (ListResponse, error) {
|
||||||
var result ListResponse
|
var result ListResponse
|
||||||
var exampleModel Model
|
var exampleModel Model
|
||||||
|
|
||||||
@ -135,6 +135,15 @@ func List(pageInfo model.PageInfo, filters []model.Filter) (ListResponse, error)
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if expand != nil {
|
||||||
|
for idx := range items {
|
||||||
|
expandErr := items[idx].Expand(expand)
|
||||||
|
if expandErr != nil {
|
||||||
|
logger.Error("CertificatesExpansionError", expandErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = ListResponse{
|
result = ListResponse{
|
||||||
Items: items,
|
Items: items,
|
||||||
Total: totalRows,
|
Total: totalRows,
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
"npm/internal/database"
|
"npm/internal/database"
|
||||||
"npm/internal/entity/certificateauthority"
|
"npm/internal/entity/certificateauthority"
|
||||||
"npm/internal/entity/dnsprovider"
|
"npm/internal/entity/dnsprovider"
|
||||||
|
"npm/internal/entity/user"
|
||||||
"npm/internal/logger"
|
"npm/internal/logger"
|
||||||
"npm/internal/types"
|
"npm/internal/types"
|
||||||
|
"npm/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -59,6 +61,7 @@ type Model struct {
|
|||||||
// Expansions:
|
// Expansions:
|
||||||
CertificateAuthority *certificateauthority.Model `json:"certificate_authority,omitempty"`
|
CertificateAuthority *certificateauthority.Model `json:"certificate_authority,omitempty"`
|
||||||
DNSProvider *dnsprovider.Model `json:"dns_provider,omitempty"`
|
DNSProvider *dnsprovider.Model `json:"dns_provider,omitempty"`
|
||||||
|
User *user.Model `json:"user,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) getByQuery(query string, params []interface{}) error {
|
func (m *Model) getByQuery(query string, params []interface{}) error {
|
||||||
@ -161,7 +164,8 @@ func (m *Model) ValidateWildcardSupport() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hasWildcard {
|
if hasWildcard {
|
||||||
m.Expand()
|
// nolint: errcheck, gosec
|
||||||
|
m.Expand([]string{"certificate-authority", "dns-provider"})
|
||||||
if !m.CertificateAuthority.IsWildcardSupported {
|
if !m.CertificateAuthority.IsWildcardSupported {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -182,15 +186,28 @@ func (m *Model) setDefaultStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expand will populate attached objects for the model
|
// Expand will populate attached objects for the model
|
||||||
func (m *Model) Expand() {
|
func (m *Model) Expand(items []string) error {
|
||||||
if m.CertificateAuthorityID > 0 {
|
var err error
|
||||||
certificateAuthority, _ := certificateauthority.GetByID(m.CertificateAuthorityID)
|
|
||||||
|
if util.SliceContainsItem(items, "certificate-authority") && m.CertificateAuthorityID > 0 {
|
||||||
|
var certificateAuthority certificateauthority.Model
|
||||||
|
certificateAuthority, err = certificateauthority.GetByID(m.CertificateAuthorityID)
|
||||||
m.CertificateAuthority = &certificateAuthority
|
m.CertificateAuthority = &certificateAuthority
|
||||||
}
|
}
|
||||||
if m.DNSProviderID > 0 {
|
|
||||||
dnsProvider, _ := dnsprovider.GetByID(m.DNSProviderID)
|
if util.SliceContainsItem(items, "dns-provider") && m.DNSProviderID > 0 {
|
||||||
|
var dnsProvider dnsprovider.Model
|
||||||
|
dnsProvider, err = dnsprovider.GetByID(m.DNSProviderID)
|
||||||
m.DNSProvider = &dnsProvider
|
m.DNSProvider = &dnsProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if util.SliceContainsItem(items, "user") && m.ID > 0 {
|
||||||
|
var usr user.Model
|
||||||
|
usr, err = user.GetByID(m.UserID)
|
||||||
|
m.User = &usr
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCertificateLocations will return the paths on disk where the SSL
|
// GetCertificateLocations will return the paths on disk where the SSL
|
||||||
@ -222,7 +239,8 @@ func (m *Model) GetCertificateLocations() (string, string, string) {
|
|||||||
func (m *Model) Request() error {
|
func (m *Model) Request() error {
|
||||||
logger.Info("Requesting certificate for: #%d %v", m.ID, m.Name)
|
logger.Info("Requesting certificate for: #%d %v", m.ID, m.Name)
|
||||||
|
|
||||||
m.Expand()
|
// nolint: errcheck, gosec
|
||||||
|
m.Expand([]string{"certificate-authority", "dns-provider"})
|
||||||
m.Status = StatusRequesting
|
m.Status = StatusRequesting
|
||||||
if err := m.Save(); err != nil {
|
if err := m.Save(); err != nil {
|
||||||
logger.Error("CertificateSaveError", err)
|
logger.Error("CertificateSaveError", err)
|
||||||
|
@ -11,7 +11,7 @@ export async function getCertificates(
|
|||||||
const { result } = await api.get(
|
const { result } = await api.get(
|
||||||
{
|
{
|
||||||
url: "certificates",
|
url: "certificates",
|
||||||
params: { limit, offset, sort, ...filters },
|
params: { limit, offset, sort, expand: "user", ...filters },
|
||||||
},
|
},
|
||||||
abortController,
|
abortController,
|
||||||
);
|
);
|
||||||
|
11
frontend/src/components/Monospace.tsx
Normal file
11
frontend/src/components/Monospace.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Text, TextProps } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
function Monospace(props: TextProps) {
|
||||||
|
return (
|
||||||
|
<Text as="span" className="monospace" {...props}>
|
||||||
|
{props.children}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Monospace };
|
@ -1,5 +1,5 @@
|
|||||||
import { Avatar, Badge, Text, Tooltip } from "@chakra-ui/react";
|
import { Avatar, Badge, Text, Tooltip } from "@chakra-ui/react";
|
||||||
import { RowAction, RowActionsMenu } from "components";
|
import { Monospace, RowAction, RowActionsMenu } from "components";
|
||||||
import { intl } from "locale";
|
import { intl } from "locale";
|
||||||
import getNiceDNSProvider from "modules/Acmesh";
|
import getNiceDNSProvider from "modules/Acmesh";
|
||||||
|
|
||||||
@ -73,13 +73,19 @@ function CapabilitiesFormatter() {
|
|||||||
|
|
||||||
function CertificateStatusFormatter() {
|
function CertificateStatusFormatter() {
|
||||||
const formatCell = ({ value }: any) => {
|
const formatCell = ({ value }: any) => {
|
||||||
return (
|
let color = "cyan.500";
|
||||||
<Badge color={value ? "cyan.500" : "red.400"}>
|
switch (value) {
|
||||||
{value
|
case "failed":
|
||||||
? intl.formatMessage({ id: "ready" })
|
color = "red.400";
|
||||||
: intl.formatMessage({ id: "setup-required" })}
|
break;
|
||||||
</Badge>
|
case "provided":
|
||||||
);
|
color = "green.400";
|
||||||
|
break;
|
||||||
|
case "requesting":
|
||||||
|
color = "yellow.400";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return <Badge color={color}>{intl.formatMessage({ id: value })}</Badge>;
|
||||||
};
|
};
|
||||||
|
|
||||||
return formatCell;
|
return formatCell;
|
||||||
@ -185,6 +191,14 @@ function HostStatusFormatter() {
|
|||||||
return formatCell;
|
return formatCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function MonospaceFormatter() {
|
||||||
|
const formatCell = ({ value }: any) => {
|
||||||
|
return <Monospace>{value}</Monospace>;
|
||||||
|
};
|
||||||
|
|
||||||
|
return formatCell;
|
||||||
|
}
|
||||||
|
|
||||||
function UpstreamStatusFormatter() {
|
function UpstreamStatusFormatter() {
|
||||||
const formatCell = ({ value, row }: any) => {
|
const formatCell = ({ value, row }: any) => {
|
||||||
if (value === "ready") {
|
if (value === "ready") {
|
||||||
@ -245,6 +259,7 @@ export {
|
|||||||
HostStatusFormatter,
|
HostStatusFormatter,
|
||||||
HostTypeFormatter,
|
HostTypeFormatter,
|
||||||
IDFormatter,
|
IDFormatter,
|
||||||
|
MonospaceFormatter,
|
||||||
SecondsFormatter,
|
SecondsFormatter,
|
||||||
UpstreamStatusFormatter,
|
UpstreamStatusFormatter,
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,7 @@ export * from "./HelpDrawer";
|
|||||||
export * from "./Loader";
|
export * from "./Loader";
|
||||||
export * from "./Loading";
|
export * from "./Loading";
|
||||||
export * from "./LocalePicker";
|
export * from "./LocalePicker";
|
||||||
|
export * from "./Monospace";
|
||||||
export * from "./Navigation";
|
export * from "./Navigation";
|
||||||
export * from "./Permissions";
|
export * from "./Permissions";
|
||||||
export * from "./PrettyButton";
|
export * from "./PrettyButton";
|
||||||
|
@ -25,6 +25,10 @@ table td.w-80 {
|
|||||||
width: 80px;
|
width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.monospace {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/* helpdoc */
|
/* helpdoc */
|
||||||
.helpdoc-body {
|
.helpdoc-body {
|
||||||
p {
|
p {
|
||||||
|
@ -3,7 +3,10 @@ import { useEffect, useMemo } from "react";
|
|||||||
import {
|
import {
|
||||||
tableEvents,
|
tableEvents,
|
||||||
ActionsFormatter,
|
ActionsFormatter,
|
||||||
|
CertificateStatusFormatter,
|
||||||
|
GravatarFormatter,
|
||||||
IDFormatter,
|
IDFormatter,
|
||||||
|
MonospaceFormatter,
|
||||||
TableFilter,
|
TableFilter,
|
||||||
TableLayout,
|
TableLayout,
|
||||||
TablePagination,
|
TablePagination,
|
||||||
@ -41,6 +44,11 @@ function CertificatesTable({
|
|||||||
}: CertificatesTableProps) {
|
}: CertificatesTableProps) {
|
||||||
const [columns, tableData] = useMemo(() => {
|
const [columns, tableData] = useMemo(() => {
|
||||||
const columns = [
|
const columns = [
|
||||||
|
{
|
||||||
|
accessor: "user.gravatarUrl",
|
||||||
|
Cell: GravatarFormatter(),
|
||||||
|
className: "w-80",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Header: intl.formatMessage({ id: "column.id" }),
|
Header: intl.formatMessage({ id: "column.id" }),
|
||||||
accessor: "id",
|
accessor: "id",
|
||||||
@ -53,6 +61,7 @@ function CertificatesTable({
|
|||||||
accessor: "name",
|
accessor: "name",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
Filter: TextFilter,
|
Filter: TextFilter,
|
||||||
|
Cell: MonospaceFormatter(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: intl.formatMessage({ id: "column.validation-type" }),
|
Header: intl.formatMessage({ id: "column.validation-type" }),
|
||||||
@ -65,6 +74,7 @@ function CertificatesTable({
|
|||||||
accessor: "status",
|
accessor: "status",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
Filter: TextFilter,
|
Filter: TextFilter,
|
||||||
|
Cell: CertificateStatusFormatter(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "actions",
|
id: "actions",
|
||||||
|
Loading…
Reference in New Issue
Block a user