Skip to content
Merged

1.21.0 #3457

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion install/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var redisFlag *bool
func main() {

crowdsecFlag := flag.Bool("crowdsec", false, "Enable the CrowdSec installation prompt")
redisFlag = flag.Bool("redis", false, "Install Redis as cacheing solution. Required for HA. Not required for the Enterprise version.")
redisFlag = flag.Bool("redis", false, "Install Redis as caching solution. Required for HA. Not required for the Enterprise version.")
flag.Parse()

// print a banner about prerequisites - opening port 80, 443, 51820, and 21820 on the VPS and firewall and pointing your domain to the VPS IP with a records. Docs are at http://localhost:3000/Getting%20Started/dns-networking
Expand Down
12 changes: 9 additions & 3 deletions messages/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
"shareDeleteConfirm": "Confirm Delete Shareable Link",
"shareQuestionRemove": "Are you sure you want to delete this share link?",
"shareMessageRemove": "Once deleted, the link will no longer work and anyone using it will lose access to the resource.",
"shareTokenDescription": "The access token can be passed in two ways: as a query parameter or in the request headers. These must be passed from the client on every request for authenticated access.",
"shareTokenDescription": "The access token can be passed as a query parameter or in request headers. By default it must be sent on every request. If session persistence is enabled, the first request exchanges it for a session cookie.",
"accessToken": "Access Token",
"usageExamples": "Usage Examples",
"tokenId": "Token ID",
Expand All @@ -196,8 +196,14 @@
"shareTitleOptional": "Title (optional)",
"sharePathOptional": "Path (optional)",
"sharePathDescription": "The link will redirect users to this path after authentication.",
"shareAssociateUserOptional": "Associate User (optional)",
"shareAssociateUserDescription": "When set, requests using this link are attributed to the user in access logs and identity headers. The link is removed if the user leaves the organization.",
"userSelect": "Select user",
"usersNotFound": "No users found",
"expireIn": "Expire In",
"neverExpire": "Never expire",
"sharePersistSession": "Persist session after first use",
"sharePersistSessionDescription": "When enabled, the first request with this token via a query param or header sets a session cookie so later requests do not need the token. Leave off for API clients that should send the token on every request.",
"shareExpireDescription": "Expiration time is how long the link will be usable and provide access to the resource. After this time, the link will no longer work, and users who used this link will lose access to the resource.",
"shareSeeOnce": "You will only be able to see this link once. Make sure to copy it.",
"shareAccessHint": "Anyone with this link can access the resource. Share it with care.",
Expand Down Expand Up @@ -3089,8 +3095,8 @@
"sourceAddress": "Source Address",
"destinationAddress": "Destination Address",
"duration": "Duration",
"licenseRequiredToUse": "An <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> license or <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> is required to use this feature. <bookADemoLink>Book a free demo or POC trial to learn more</bookADemoLink>.",
"ossEnterpriseEditionRequired": "The <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> is required to use this feature. This feature is also available in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>. <bookADemoLink>Book a free demo or POC trial to learn more</bookADemoLink>.",
"licenseRequiredToUse": "An <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> license or <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> is required to use this feature. <bookADemoLink>Book a free demo or POC trial to learn more.</bookADemoLink>",
"ossEnterpriseEditionRequired": "The <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> is required to use this feature. This feature is also available in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>. <bookADemoLink>Book a free demo or POC trial to learn more.</bookADemoLink>",
"certResolver": "Certificate Resolver",
"certResolverDescription": "Select the certificate resolver to use for this resource.",
"selectCertResolver": "Select Certificate Resolver",
Expand Down
5 changes: 5 additions & 0 deletions server/db/pg/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export const sites = pgTable(
lastPing: integer("lastPing"),
address: varchar("address"),
endpoint: varchar("endpoint"),
localEndpoints: varchar("localEndpoints"), // JSON encoded list of string ips on the local machine to try to connect to
publicKey: varchar("publicKey"),
lastHolePunch: bigint("lastHolePunch", { mode: "number" }),
listenPort: integer("listenPort"),
Expand Down Expand Up @@ -905,12 +906,16 @@ export const resourceAccessToken = pgTable("resourceAccessToken", {
resourceId: integer("resourceId")
.notNull()
.references(() => resources.resourceId, { onDelete: "cascade" }),
userId: varchar("userId").references(() => users.userId, {
onDelete: "cascade"
}),
path: varchar("path"),
tokenHash: varchar("tokenHash").notNull(),
sessionLength: bigint("sessionLength", { mode: "number" }).notNull(),
expiresAt: bigint("expiresAt", { mode: "number" }),
title: varchar("title"),
description: varchar("description"),
persistSession: boolean("persistSession").notNull().default(false),
createdAt: bigint("createdAt", { mode: "number" }).notNull()
});

Expand Down
7 changes: 7 additions & 0 deletions server/db/sqlite/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export const sites = sqliteTable("sites", {
// exit node stuff that is how to connect to the site when it has a wg server
address: text("address"), // this is the address of the wireguard interface in newt
endpoint: text("endpoint"), // this is how to reach gerbil externally - gets put into the wireguard config
localEndpoints: text("localEndpoints"), // JSON encoded list of string ips on the local machine to try to connect to
publicKey: text("publicKey"), // TODO: Fix typo in publicKey
lastHolePunch: integer("lastHolePunch"),
listenPort: integer("listenPort"),
Expand Down Expand Up @@ -1125,12 +1126,18 @@ export const resourceAccessToken = sqliteTable("resourceAccessToken", {
resourceId: integer("resourceId")
.notNull()
.references(() => resources.resourceId, { onDelete: "cascade" }),
userId: text("userId").references(() => users.userId, {
onDelete: "cascade"
}),
path: text("path"),
tokenHash: text("tokenHash").notNull(),
sessionLength: integer("sessionLength").notNull(),
expiresAt: integer("expiresAt"),
title: text("title"),
description: text("description"),
persistSession: integer("persistSession", { mode: "boolean" })
.notNull()
.default(false),
createdAt: integer("createdAt").notNull()
});

Expand Down
2 changes: 1 addition & 1 deletion server/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url";

// This is a placeholder value replaced by the build process
export const APP_VERSION = "1.20.0";
export const APP_VERSION = "1.21.0";

export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);
Expand Down
10 changes: 10 additions & 0 deletions server/lib/userOrg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
db,
Org,
orgs,
resourceAccessToken,
resources,
siteResources,
sites,
Expand Down Expand Up @@ -83,6 +84,15 @@ export async function removeUserFromOrg(
.delete(userOrgs)
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, org.orgId)));

await trx
.delete(resourceAccessToken)
.where(
and(
eq(resourceAccessToken.userId, userId),
eq(resourceAccessToken.orgId, org.orgId)
)
);

await trx.delete(userResources).where(
and(
eq(userResources.userId, userId),
Expand Down
Loading
Loading