diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
index b2e9bdf3..f4e9a487 100644
--- a/.github/workflows/cicd.yml
+++ b/.github/workflows/cicd.yml
@@ -49,13 +49,20 @@ jobs:
LATEST_TAG=$(curl -s https://api.github.com/repos/fosrl/gerbil/tags | jq -r '.[0].name')
echo "LATEST_GERBIL_TAG=$LATEST_TAG" >> $GITHUB_ENV
+ - name: Pull latest Badger version
+ id: get-badger-tag
+ run: |
+ LATEST_TAG=$(curl -s https://api.github.com/repos/fosrl/badger/tags | jq -r '.[0].name')
+ echo "LATEST_BADGER_TAG=$LATEST_TAG" >> $GITHUB_ENV
+
- name: Update install/main.go
run: |
PANGOLIN_VERSION=${{ env.TAG }}
GERBIL_VERSION=${{ env.LATEST_GERBIL_TAG }}
sed -i "s/config.PangolinVersion = \".*\"/config.PangolinVersion = \"$PANGOLIN_VERSION\"/" install/main.go
sed -i "s/config.GerbilVersion = \".*\"/config.GerbilVersion = \"$GERBIL_VERSION\"/" install/main.go
- echo "Updated install/main.go with Pangolin version $PANGOLIN_VERSION and Gerbil version $GERBIL_VERSION"
+ sed -i "s/config.BadgerVersion = \".*\"/config.BadgerVersion = \"$BADGER_VERSION\"/" install/main.go
+ echo "Updated install/main.go with Pangolin version $PANGOLIN_VERSION, Gerbil version $GERBIL_VERSION, and Badger version $BADGER_VERSION"
cat install/main.go
- name: Build and push Docker images
diff --git a/install/main.go b/install/main.go
index d8136dda..4f2deb3a 100644
--- a/install/main.go
+++ b/install/main.go
@@ -489,4 +489,4 @@ func pullAndStartContainers() error {
}
return nil
-}
\ No newline at end of file
+}
diff --git a/server/emails/templates/ResourceOTPCode.tsx b/server/emails/templates/ResourceOTPCode.tsx
index a672235a..086dc444 100644
--- a/server/emails/templates/ResourceOTPCode.tsx
+++ b/server/emails/templates/ResourceOTPCode.tsx
@@ -44,7 +44,7 @@ export const ResourceOTPCode = ({
- Your One-Time Password for {resourceName}
+ Your One-Time Code for {resourceName}
Hi {email || "there"},
diff --git a/server/setup/scripts/1.0.0-beta9.ts b/server/setup/scripts/1.0.0-beta9.ts
index f82f7012..32fd8e37 100644
--- a/server/setup/scripts/1.0.0-beta9.ts
+++ b/server/setup/scripts/1.0.0-beta9.ts
@@ -20,216 +20,204 @@ import { fromZodError } from "zod-validation-error";
export default async function migration() {
console.log("Running setup script 1.0.0-beta.9...");
- try {
- await db.transaction(async (trx) => {
- trx.run(sql`UPDATE ${users} SET email = LOWER(email);`);
- trx.run(
- sql`UPDATE ${emailVerificationCodes} SET email = LOWER(email);`
- );
- trx.run(
- sql`UPDATE ${passwordResetTokens} SET email = LOWER(email);`
- );
- trx.run(sql`UPDATE ${userInvites} SET email = LOWER(email);`);
- trx.run(sql`UPDATE ${resourceWhitelist} SET email = LOWER(email);`);
- trx.run(sql`UPDATE ${resourceOtp} SET email = LOWER(email);`);
- });
- } catch (error) {
- console.log(
- "We were unable to make all emails lower case in the database. You can safely ignore this error."
- );
- console.error(error);
- }
+ await db.transaction(async (trx) => {
+ try {
+ // Determine which config file exists
+ const filePaths = [configFilePath1, configFilePath2];
+ let filePath = "";
+ for (const path of filePaths) {
+ if (fs.existsSync(path)) {
+ filePath = path;
+ break;
+ }
+ }
- try {
- await db.transaction(async (trx) => {
-
- const resourcesAll = await trx.select({
+ if (!filePath) {
+ throw new Error(
+ `No config file found (expected config.yml or config.yaml).`
+ );
+ }
+
+ // Read and parse the YAML file
+ let rawConfig: any;
+ const fileContents = fs.readFileSync(filePath, "utf8");
+ rawConfig = yaml.load(fileContents);
+
+ rawConfig.server.resource_session_request_param =
+ "p_session_request";
+ rawConfig.server.session_cookie_name = "p_session_token"; // rename to prevent conflicts
+ delete rawConfig.server.resource_session_cookie_name;
+
+ // Write the updated YAML back to the file
+ const updatedYaml = yaml.dump(rawConfig);
+ fs.writeFileSync(filePath, updatedYaml, "utf8");
+ } catch (e) {
+ console.log(
+ `Failed to add resource_session_request_param to config. Please add it manually. https://docs.fossorial.io/Pangolin/Configuration/config`
+ );
+ trx.rollback();
+ return;
+ }
+
+ try {
+ const traefikPath = path.join(
+ APP_PATH,
+ "traefik",
+ "traefik_config.yml"
+ );
+
+ // Define schema for traefik config validation
+ const schema = z.object({
+ entryPoints: z
+ .object({
+ websecure: z
+ .object({
+ address: z.string(),
+ transport: z
+ .object({
+ respondingTimeouts: z.object({
+ readTimeout: z.string()
+ })
+ })
+ .optional()
+ })
+ .optional()
+ })
+ .optional(),
+ experimental: z.object({
+ plugins: z.object({
+ badger: z.object({
+ moduleName: z.string(),
+ version: z.string()
+ })
+ })
+ })
+ });
+
+ const traefikFileContents = fs.readFileSync(traefikPath, "utf8");
+ const traefikConfig = yaml.load(traefikFileContents) as any;
+
+ const parsedConfig = schema.safeParse(traefikConfig);
+
+ if (parsedConfig.success) {
+ // Ensure websecure entrypoint exists
+ if (traefikConfig.entryPoints?.websecure) {
+ // Add transport configuration
+ traefikConfig.entryPoints.websecure.transport = {
+ respondingTimeouts: {
+ readTimeout: "30m"
+ }
+ };
+ }
+
+ traefikConfig.experimental.plugins.badger.version =
+ "v1.0.0-beta.3";
+
+ const updatedTraefikYaml = yaml.dump(traefikConfig);
+ fs.writeFileSync(traefikPath, updatedTraefikYaml, "utf8");
+
+ console.log(
+ "Updated the version of Badger in your Traefik configuration to v1.0.0-beta.3 and added readTimeout to websecure entrypoint in your Traefik configuration.."
+ );
+ } else {
+ console.log(fromZodError(parsedConfig.error));
+ console.log(
+ "We were unable to update the version of Badger in your Traefik configuration. Please update it manually to at least v1.0.0-beta.3. https://github.com/fosrl/badger"
+ );
+ }
+ } catch (e) {
+ console.log(
+ "We were unable to update the version of Badger in your Traefik configuration. Please update it manually to at least v1.0.0-beta.3. https://github.com/fosrl/badger"
+ );
+ trx.rollback();
+ return;
+ }
+
+ trx.run(sql`UPDATE ${users} SET email = LOWER(email);`);
+ trx.run(
+ sql`UPDATE ${emailVerificationCodes} SET email = LOWER(email);`
+ );
+ trx.run(sql`UPDATE ${passwordResetTokens} SET email = LOWER(email);`);
+ trx.run(sql`UPDATE ${userInvites} SET email = LOWER(email);`);
+ trx.run(sql`UPDATE ${resourceWhitelist} SET email = LOWER(email);`);
+ trx.run(sql`UPDATE ${resourceOtp} SET email = LOWER(email);`);
+
+ const resourcesAll = await trx
+ .select({
resourceId: resources.resourceId,
fullDomain: resources.fullDomain,
subdomain: resources.subdomain
- }).from(resources);
+ })
+ .from(resources);
- trx.run(`DROP INDEX resources_fullDomain_unique;`)
- trx.run(`ALTER TABLE resources
+ trx.run(`DROP INDEX resources_fullDomain_unique;`);
+ trx.run(`ALTER TABLE resources
DROP COLUMN fullDomain;
- `)
- trx.run(`ALTER TABLE resources
+ `);
+ trx.run(`ALTER TABLE resources
DROP COLUMN subdomain;
- `)
- trx.run(sql`ALTER TABLE resources
+ `);
+ trx.run(sql`ALTER TABLE resources
ADD COLUMN fullDomain TEXT;
- `)
- trx.run(sql`ALTER TABLE resources
+ `);
+ trx.run(sql`ALTER TABLE resources
ADD COLUMN subdomain TEXT;
- `)
- trx.run(sql`ALTER TABLE resources
+ `);
+ trx.run(sql`ALTER TABLE resources
ADD COLUMN http INTEGER DEFAULT true NOT NULL;
- `)
- trx.run(sql`ALTER TABLE resources
+ `);
+ trx.run(sql`ALTER TABLE resources
ADD COLUMN protocol TEXT DEFAULT 'tcp' NOT NULL;
- `)
- trx.run(sql`ALTER TABLE resources
+ `);
+ trx.run(sql`ALTER TABLE resources
ADD COLUMN proxyPort INTEGER;
- `)
+ `);
- // write the new fullDomain and subdomain values back to the database
- for (const resource of resourcesAll) {
- await trx.update(resources).set({
+ // write the new fullDomain and subdomain values back to the database
+ for (const resource of resourcesAll) {
+ await trx
+ .update(resources)
+ .set({
fullDomain: resource.fullDomain,
subdomain: resource.subdomain
- }).where(eq(resources.resourceId, resource.resourceId));
- }
+ })
+ .where(eq(resources.resourceId, resource.resourceId));
+ }
- const targetsAll = await trx.select({
+ const targetsAll = await trx
+ .select({
targetId: targets.targetId,
method: targets.method
- }).from(targets);
-
- trx.run(`ALTER TABLE targets
- DROP COLUMN method;
- `)
- trx.run(`ALTER TABLE targets
- DROP COLUMN protocol;
- `)
- trx.run(sql`ALTER TABLE targets
- ADD COLUMN method TEXT;
- `)
-
- // write the new method and protocol values back to the database
- for (const target of targetsAll) {
- await trx.update(targets).set({
- method: target.method
- }).where(eq(targets.targetId, target.targetId));
- }
-
- });
- } catch (error) {
- console.log(
- "We were unable to make the changes to the targets and resources tables."
- );
- throw error;
- }
-
- try {
- // Determine which config file exists
- const filePaths = [configFilePath1, configFilePath2];
- let filePath = "";
- for (const path of filePaths) {
- if (fs.existsSync(path)) {
- filePath = path;
- break;
- }
- }
-
- if (!filePath) {
- throw new Error(
- `No config file found (expected config.yml or config.yaml).`
- );
- }
-
- // Read and parse the YAML file
- let rawConfig: any;
- const fileContents = fs.readFileSync(filePath, "utf8");
- rawConfig = yaml.load(fileContents);
-
- rawConfig.server.resource_session_request_param = "p_session_request";
- rawConfig.server.session_cookie_name = "p_session_token"; // rename to prevent conflicts
- delete rawConfig.server.resource_session_cookie_name;
-
- // Write the updated YAML back to the file
- const updatedYaml = yaml.dump(rawConfig);
- fs.writeFileSync(filePath, updatedYaml, "utf8");
- } catch (e) {
- console.log(
- `Failed to add resource_session_request_param to config. Please add it manually. https://docs.fossorial.io/Pangolin/Configuration/config`
- );
- throw e;
- }
-
- try {
- const traefikPath = path.join(
- APP_PATH,
- "traefik",
- "traefik_config.yml"
- );
-
- // Define schema for traefik config validation
- const schema = z.object({
- entryPoints: z
- .object({
- websecure: z
- .object({
- address: z.string(),
- transport: z
- .object({
- respondingTimeouts: z.object({
- readTimeout: z.string()
- })
- })
- .optional()
- })
- .optional()
- })
- .optional(),
- experimental: z.object({
- plugins: z.object({
- badger: z.object({
- moduleName: z.string(),
- version: z.string()
- })
- })
})
- });
+ .from(targets);
- const traefikFileContents = fs.readFileSync(traefikPath, "utf8");
- const traefikConfig = yaml.load(traefikFileContents) as any;
+ trx.run(`ALTER TABLE targets
+ DROP COLUMN method;
+ `);
+ trx.run(`ALTER TABLE targets
+ DROP COLUMN protocol;
+ `);
+ trx.run(sql`ALTER TABLE targets
+ ADD COLUMN method TEXT;
+ `);
- const parsedConfig = schema.safeParse(traefikConfig);
-
- if (!parsedConfig.success) {
- throw new Error(fromZodError(parsedConfig.error).toString());
+ // write the new method and protocol values back to the database
+ for (const target of targetsAll) {
+ await trx
+ .update(targets)
+ .set({
+ method: target.method
+ })
+ .where(eq(targets.targetId, target.targetId));
}
- // Ensure websecure entrypoint exists
- if (traefikConfig.entryPoints?.websecure) {
- // Add transport configuration
- traefikConfig.entryPoints.websecure.transport = {
- respondingTimeouts: {
- readTimeout: "30m"
- }
- };
- }
-
- traefikConfig.experimental.plugins.badger.version = "v1.0.0-beta.3";
-
- const updatedTraefikYaml = yaml.dump(traefikConfig);
- fs.writeFileSync(traefikPath, updatedTraefikYaml, "utf8");
-
- console.log(
- "Updated the version of Badger in your Traefik configuration to v1.0.0-beta.3 and added readTimeout to websecure entrypoint in your Traefik configuration.."
+ trx.run(
+ sql`ALTER TABLE 'resourceSessions' ADD 'isRequestToken' integer;`
);
- } catch (e) {
- console.log(
- "We were unable to update the version of Badger in your Traefik configuration. Please update it manually to at least v1.0.0-beta.3. https://github.com/fosrl/badger"
+ trx.run(
+ sql`ALTER TABLE 'resourceSessions' ADD 'userSessionId' text REFERENCES session(id);`
);
- throw e;
- }
-
- try {
- await db.transaction(async (trx) => {
- trx.run(
- sql`ALTER TABLE 'resourceSessions' ADD 'isRequestToken' integer;`
- );
- trx.run(
- sql`ALTER TABLE 'resourceSessions' ADD 'userSessionId' text REFERENCES session(id);`
- );
- });
- } catch (e) {
- console.log(
- "We were unable to add columns to the resourceSessions table."
- );
- throw e;
- }
+ });
console.log("Done.");
}