mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-19 09:06:37 +00:00
Compare commits
4 Commits
dependabot
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03288d2a60 | ||
|
|
1169b68619 | ||
|
|
d3bfd67738 | ||
|
|
d44292cf33 |
14
.github/workflows/cicd.yml
vendored
14
.github/workflows/cicd.yml
vendored
@@ -77,7 +77,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
@@ -204,7 +204,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
@@ -264,7 +264,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
with:
|
||||
go-version: 1.24
|
||||
|
||||
@@ -299,7 +299,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Upload artifacts from /install/bin
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: install-bin
|
||||
path: install/bin/
|
||||
@@ -407,7 +407,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Login to GitHub Container Registry (for cosign)
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -415,7 +415,7 @@ jobs:
|
||||
|
||||
- name: Install cosign
|
||||
# cosign is used to sign and verify container images (key and keyless)
|
||||
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Dual-sign and verify (GHCR & Docker Hub)
|
||||
# Sign each image by digest using keyless (OIDC) and key-based signing,
|
||||
|
||||
2
.github/workflows/linting.yml
vendored
2
.github/workflows/linting.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
|
||||
2
.github/workflows/mirror.yaml
vendored
2
.github/workflows/mirror.yaml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
skopeo --version
|
||||
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Input check
|
||||
run: |
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
|
||||
13
README.md
13
README.md
@@ -43,7 +43,7 @@
|
||||
|
||||
<p align="center">
|
||||
<strong>
|
||||
Get started with Pangolin at <a href="https://app.pangolin.net/auth/signup">app.pangolin.net</a>
|
||||
Start testing Pangolin at <a href="https://app.pangolin.net/auth/signup">app.pangolin.net</a>
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
@@ -60,9 +60,9 @@ Pangolin is an open-source, identity-based remote access platform built on WireG
|
||||
|
||||
| <img width=500 /> | Description |
|
||||
|-----------------|--------------|
|
||||
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing — no infrastructure required. Or, self-host your own [remote node](https://docs.pangolin.net/manage/remote-node/understanding-nodes) and connect to our control plane. |
|
||||
| **Self-Host: Community Edition** | Free, open source, and licensed under AGPL-3. |
|
||||
| **Self-Host: Enterprise Edition** | Licensed under Fossorial Commercial License. Free for personal and hobbyist use, and for businesses earning under \$100K USD annually. |
|
||||
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing — no infrastructure required. Or, self-host your own [remote node](https://docs.pangolin.net/manage/remote-node/nodes) and connect to our control plane. |
|
||||
|
||||
## Key Features
|
||||
|
||||
@@ -85,16 +85,17 @@ Download the Pangolin client for your platform:
|
||||
|
||||
## Get Started
|
||||
|
||||
### Sign up now
|
||||
|
||||
Create an account at [app.pangolin.net](https://app.pangolin.net) to get started with Pangolin Cloud. A generous free tier is available.
|
||||
|
||||
### Check out the docs
|
||||
|
||||
We encourage everyone to read the full documentation first, which is
|
||||
available at [docs.pangolin.net](https://docs.pangolin.net). This README provides only a very brief subset of
|
||||
the docs to illustrate some basic ideas.
|
||||
|
||||
### Sign up and try now
|
||||
|
||||
For Pangolin's managed service, you will first need to create an account at
|
||||
[app.pangolin.net](https://app.pangolin.net). We have a generous free tier to get started.
|
||||
|
||||
## Licensing
|
||||
|
||||
Pangolin is dual licensed under the AGPL-3 and the [Fossorial Commercial License](https://pangolin.net/fcl.html). For inquiries about commercial licensing, please contact us at [contact@pangolin.net](mailto:contact@pangolin.net).
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module installer
|
||||
|
||||
go 1.25.0
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/huh v0.8.0
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
golang.org/x/term v0.41.0
|
||||
golang.org/x/term v0.40.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
@@ -33,6 +33,6 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
)
|
||||
|
||||
@@ -69,10 +69,10 @@ golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
|
||||
@@ -1120,7 +1120,6 @@
|
||||
"setupTokenDescription": "Enter the setup token from the server console.",
|
||||
"setupTokenRequired": "Setup token is required",
|
||||
"actionUpdateSite": "Update Site",
|
||||
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
|
||||
"actionListSiteRoles": "List Allowed Site Roles",
|
||||
"actionCreateResource": "Create Resource",
|
||||
"actionDeleteResource": "Delete Resource",
|
||||
|
||||
2646
package-lock.json
generated
2646
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@@ -33,7 +33,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@asteasolutions/zod-to-openapi": "8.4.1",
|
||||
"@aws-sdk/client-s3": "3.1011.0",
|
||||
"@aws-sdk/client-s3": "3.1004.0",
|
||||
"@faker-js/faker": "10.3.0",
|
||||
"@headlessui/react": "2.2.9",
|
||||
"@hookform/resolvers": "5.2.2",
|
||||
@@ -62,8 +62,8 @@
|
||||
"@react-email/components": "1.0.8",
|
||||
"@react-email/render": "2.0.4",
|
||||
"@react-email/tailwind": "2.0.5",
|
||||
"@simplewebauthn/browser": "13.3.0",
|
||||
"@simplewebauthn/server": "13.3.0",
|
||||
"@simplewebauthn/browser": "13.2.2",
|
||||
"@simplewebauthn/server": "13.2.3",
|
||||
"@tailwindcss/forms": "0.5.11",
|
||||
"@tanstack/react-query": "5.90.21",
|
||||
"@tanstack/react-table": "8.21.3",
|
||||
@@ -133,8 +133,8 @@
|
||||
"devDependencies": {
|
||||
"@dotenvx/dotenvx": "1.54.1",
|
||||
"@esbuild-plugins/tsconfig-paths": "0.1.2",
|
||||
"@react-email/preview-server": "5.2.10",
|
||||
"@tailwindcss/postcss": "4.2.2",
|
||||
"@react-email/preview-server": "5.2.8",
|
||||
"@tailwindcss/postcss": "4.2.1",
|
||||
"@tanstack/react-query-devtools": "5.91.3",
|
||||
"@types/better-sqlite3": "7.6.13",
|
||||
"@types/cookie-parser": "1.4.10",
|
||||
@@ -159,15 +159,15 @@
|
||||
"@types/ws": "8.18.1",
|
||||
"@types/yargs": "17.0.35",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"drizzle-kit": "0.31.10",
|
||||
"drizzle-kit": "0.31.9",
|
||||
"esbuild": "0.27.3",
|
||||
"esbuild-node-externals": "1.20.1",
|
||||
"eslint": "10.0.3",
|
||||
"eslint-config-next": "16.1.7",
|
||||
"postcss": "8.5.8",
|
||||
"eslint": "9.39.2",
|
||||
"eslint-config-next": "16.1.6",
|
||||
"postcss": "8.5.6",
|
||||
"prettier": "3.8.1",
|
||||
"react-email": "5.2.10",
|
||||
"tailwindcss": "4.2.2",
|
||||
"react-email": "5.2.8",
|
||||
"tailwindcss": "4.2.1",
|
||||
"tsc-alias": "1.8.16",
|
||||
"tsx": "4.21.0",
|
||||
"typescript": "5.9.3",
|
||||
|
||||
@@ -19,7 +19,6 @@ export enum ActionsEnum {
|
||||
getSite = "getSite",
|
||||
listSites = "listSites",
|
||||
updateSite = "updateSite",
|
||||
resetSiteBandwidth = "resetSiteBandwidth",
|
||||
reGenerateSecret = "reGenerateSecret",
|
||||
createResource = "createResource",
|
||||
deleteResource = "deleteResource",
|
||||
|
||||
@@ -286,14 +286,12 @@ export class TraefikConfigManager {
|
||||
// Check non-wildcard certs for expiry (within 45 days to match
|
||||
// the server-side renewal window in certificate-service)
|
||||
for (const domain of domainsNeedingCerts) {
|
||||
const localState =
|
||||
this.lastLocalCertificateState.get(domain);
|
||||
const localState = this.lastLocalCertificateState.get(domain);
|
||||
if (localState?.expiresAt) {
|
||||
const nowInSeconds = Math.floor(Date.now() / 1000);
|
||||
const secondsUntilExpiry =
|
||||
localState.expiresAt - nowInSeconds;
|
||||
const daysUntilExpiry =
|
||||
secondsUntilExpiry / (60 * 60 * 24);
|
||||
const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24);
|
||||
if (daysUntilExpiry < 45) {
|
||||
logger.info(
|
||||
`Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)`
|
||||
@@ -306,18 +304,11 @@ export class TraefikConfigManager {
|
||||
// Also check wildcard certificates for expiry. These are not
|
||||
// included in domainsNeedingCerts since their subdomains are
|
||||
// filtered out, so we must check them separately.
|
||||
for (const [certDomain, state] of this
|
||||
.lastLocalCertificateState) {
|
||||
if (
|
||||
state.exists &&
|
||||
state.wildcard &&
|
||||
state.expiresAt
|
||||
) {
|
||||
for (const [certDomain, state] of this.lastLocalCertificateState) {
|
||||
if (state.exists && state.wildcard && state.expiresAt) {
|
||||
const nowInSeconds = Math.floor(Date.now() / 1000);
|
||||
const secondsUntilExpiry =
|
||||
state.expiresAt - nowInSeconds;
|
||||
const daysUntilExpiry =
|
||||
secondsUntilExpiry / (60 * 60 * 24);
|
||||
const secondsUntilExpiry = state.expiresAt - nowInSeconds;
|
||||
const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24);
|
||||
if (daysUntilExpiry < 45) {
|
||||
logger.info(
|
||||
`Fetching certificates due to upcoming expiry for wildcard cert ${certDomain} (${Math.round(daysUntilExpiry)} days remaining)`
|
||||
@@ -405,14 +396,8 @@ export class TraefikConfigManager {
|
||||
// their subdomains were filtered out above.
|
||||
for (const [certDomain, state] of this
|
||||
.lastLocalCertificateState) {
|
||||
if (
|
||||
state.exists &&
|
||||
state.wildcard &&
|
||||
state.expiresAt
|
||||
) {
|
||||
const nowInSeconds = Math.floor(
|
||||
Date.now() / 1000
|
||||
);
|
||||
if (state.exists && state.wildcard && state.expiresAt) {
|
||||
const nowInSeconds = Math.floor(Date.now() / 1000);
|
||||
const secondsUntilExpiry =
|
||||
state.expiresAt - nowInSeconds;
|
||||
const daysUntilExpiry =
|
||||
@@ -572,11 +557,18 @@ export class TraefikConfigManager {
|
||||
config.getRawConfig().server
|
||||
.session_cookie_name,
|
||||
|
||||
// deprecated
|
||||
accessTokenQueryParam:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_param,
|
||||
|
||||
accessTokenIdHeader:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_headers.id,
|
||||
|
||||
accessTokenHeader:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_headers.token,
|
||||
|
||||
resourceSessionRequestParam:
|
||||
config.getRawConfig().server
|
||||
.resource_session_request_param
|
||||
|
||||
@@ -135,13 +135,6 @@ authenticated.post(
|
||||
logActionAudit(ActionsEnum.updateSite),
|
||||
site.updateSite
|
||||
);
|
||||
authenticated.post(
|
||||
"/org/:orgId/reset-bandwidth",
|
||||
verifyApiKeyOrgAccess,
|
||||
verifyApiKeyHasAction(ActionsEnum.resetSiteBandwidth),
|
||||
logActionAudit(ActionsEnum.resetSiteBandwidth),
|
||||
org.resetOrgBandwidth
|
||||
);
|
||||
|
||||
authenticated.delete(
|
||||
"/site/:siteId",
|
||||
|
||||
@@ -14,7 +14,11 @@ import logger from "@server/logger";
|
||||
import { initPeerAddHandshake, updatePeer } from "../olm/peers";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import config from "@server/lib/config";
|
||||
import { generateSubnetProxyTargets, SubnetProxyTarget } from "@server/lib/ip";
|
||||
import {
|
||||
formatEndpoint,
|
||||
generateSubnetProxyTargets,
|
||||
SubnetProxyTarget
|
||||
} from "@server/lib/ip";
|
||||
|
||||
export async function buildClientConfigurationForNewtClient(
|
||||
site: Site,
|
||||
@@ -219,8 +223,8 @@ export async function buildTargetConfigurationForNewtClient(siteId: number) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
// Format target into string
|
||||
const formattedTarget = `${target.internalPort}:${target.ip}:${target.port}`;
|
||||
// Format target into string (handles IPv6 bracketing)
|
||||
const formattedTarget = `${target.internalPort}:${formatEndpoint(target.ip, target.port)}`;
|
||||
|
||||
// Add to the appropriate protocol array
|
||||
if (target.protocol === "tcp") {
|
||||
|
||||
@@ -8,4 +8,3 @@ export * from "./getOrgOverview";
|
||||
export * from "./listOrgs";
|
||||
export * from "./pickOrgDefaults";
|
||||
export * from "./checkOrgUserAccess";
|
||||
export * from "./resetOrgBandwidth";
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { z } from "zod";
|
||||
import { db, sites } from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const resetOrgBandwidthParamsSchema = z.strictObject({
|
||||
orgId: z.string()
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "post",
|
||||
path: "/org/{orgId}/reset-bandwidth",
|
||||
description: "Reset all sites in selected organization bandwidth counters.",
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: resetOrgBandwidthParamsSchema
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function resetOrgBandwidth(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedParams = resetOrgBandwidthParamsSchema.safeParse(
|
||||
req.params
|
||||
);
|
||||
if (!parsedParams.success) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
fromError(parsedParams.error).toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const { orgId } = parsedParams.data;
|
||||
|
||||
const [site] = await db
|
||||
.select({ siteId: sites.siteId })
|
||||
.from(sites)
|
||||
.where(eq(sites.orgId, orgId))
|
||||
.limit(1);
|
||||
|
||||
if (!site) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`No sites found in org ${orgId}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await db
|
||||
.update(sites)
|
||||
.set({
|
||||
megabytesIn: 0,
|
||||
megabytesOut: 0
|
||||
})
|
||||
.where(eq(sites.orgId, orgId));
|
||||
|
||||
return response(res, {
|
||||
data: {},
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Sites bandwidth reset successfully",
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -39,11 +39,18 @@ export async function traefikConfigProvider(
|
||||
userSessionCookieName:
|
||||
config.getRawConfig().server.session_cookie_name,
|
||||
|
||||
// deprecated
|
||||
accessTokenQueryParam:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_param,
|
||||
|
||||
accessTokenIdHeader:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_headers.id,
|
||||
|
||||
accessTokenHeader:
|
||||
config.getRawConfig().server
|
||||
.resource_access_token_headers.token,
|
||||
|
||||
resourceSessionRequestParam:
|
||||
config.getRawConfig().server
|
||||
.resource_session_request_param
|
||||
|
||||
@@ -129,6 +129,11 @@ const ResourceInfo = ({ resource }: { resource: Resource }) => {
|
||||
resource.pincode ||
|
||||
resource.whitelist;
|
||||
|
||||
const hasAnyInfo =
|
||||
Boolean(resource.siteName) || Boolean(hasAuthMethods) || !resource.enabled;
|
||||
|
||||
if (!hasAnyInfo) return null;
|
||||
|
||||
const infoContent = (
|
||||
<div className="flex flex-col gap-3">
|
||||
{/* Site Information */}
|
||||
@@ -828,6 +833,12 @@ export default function MemberResourcesPortal({
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<span className="font-medium">Destination:</span>
|
||||
<span className="ml-2 text-muted-foreground">
|
||||
{siteResource.destination}
|
||||
</span>
|
||||
</div>
|
||||
{siteResource.alias && (
|
||||
<div>
|
||||
<span className="font-medium">Alias:</span>
|
||||
@@ -836,14 +847,6 @@ export default function MemberResourcesPortal({
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{siteResource.aliasAddress && (
|
||||
<div>
|
||||
<span className="font-medium">Alias Address:</span>
|
||||
<span className="ml-2 text-muted-foreground">
|
||||
{siteResource.aliasAddress}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<span className="font-medium">Status:</span>
|
||||
<span className={`ml-2 ${siteResource.enabled ? 'text-green-600' : 'text-red-600'}`}>
|
||||
|
||||
@@ -26,7 +26,6 @@ function getActionsCategories(root: boolean) {
|
||||
[t("actionGetOrg")]: "getOrg",
|
||||
[t("actionUpdateOrg")]: "updateOrg",
|
||||
[t("actionGetOrgUser")]: "getOrgUser",
|
||||
[t("actionResetSiteBandwidth")]: "resetSiteBandwidth",
|
||||
[t("actionInviteUser")]: "inviteUser",
|
||||
[t("actionRemoveInvitation")]: "removeInvitation",
|
||||
[t("actionListInvitations")]: "listInvitations",
|
||||
|
||||
Reference in New Issue
Block a user