diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml index 3e693915fe6f99a5c2221b2921bf8ebc305180fc..5e11e5c312f62bed34d8cc68bd4a5538f52476b9 100644 --- a/.github/workflows/fly-deploy.yml +++ b/.github/workflows/fly-deploy.yml @@ -3,11 +3,11 @@ name: deploy to fly.io on: push: branches: - - main + - staging workflow_dispatch: concurrency: - group: fly-deploy-main + group: fly-deploy-staging cancel-in-progress: true jobs: diff --git a/borter/src/app/linear.clj b/borter/src/app/linear.clj index f77d8a974e0cf05f9c33233bb625bdb190d2007b..5ef0e34cf1d543826675c6facb66aec079b40561 100644 --- a/borter/src/app/linear.clj +++ b/borter/src/app/linear.clj @@ -6,6 +6,7 @@ [ring.util.response :as response] [app.database :as db] [app.permissions :as perms] + [app.util :as util] [honey.sql.helpers :as h] [sluj.core :refer [sluj]])) @@ -13,9 +14,7 @@ (def client-secret (System/getenv "BORTER_LINEAR_CLIENT_SECRET")) (defn get-hostname [] - (case (.getCanonicalHostName (java.net.InetAddress/getLocalHost)) - "sorter.social" "https://sorter.social/api/linear/callback" - "http://localhost:3000/api/linear/callback")) + (str (util/get-base-url) "/api/linear/callback")) (defn code->token [code] (def code code) diff --git a/borter/src/app/login.clj b/borter/src/app/login.clj index 5d545db9bef7765ba8b3fe7d00261c8ce84e9e1a..86817f8e94bc174e5b108859cc0b342953ab7acb 100644 --- a/borter/src/app/login.clj +++ b/borter/src/app/login.clj @@ -1,6 +1,7 @@ (ns app.login (:require [crypto.password.bcrypt :as password] [app.database :as db] + [app.util :as util] [honey.sql.helpers :as h] [hato.client :as hc] [clojure.data.json :as json] @@ -12,10 +13,7 @@ (def environment (or (System/getenv "ENVIRONMENT") "development")) (defn get-base-url [] - (case environment - "production" "https://sorter.social" - "staging" "https://staging.sorter.social" - "development" "http://localhost:3000")) ; fallback for development + (util/get-base-url)) (defn create-email-content "Creates a standardized email structure with customizable content" diff --git a/borter/src/app/oauth.clj b/borter/src/app/oauth.clj index 1166f2ee30c9e813840711c72d1ad8f1c62e1ffe..2cd0c62f1fe267f7f5f725a97bc3ba0d0889517f 100644 --- a/borter/src/app/oauth.clj +++ b/borter/src/app/oauth.clj @@ -3,6 +3,7 @@ [clojure.data.json :as json] [hato.client :as hc] [app.database :as db] + [app.util :as util] [honey.sql.helpers :as h] [ring.util.codec :as codec]) (:import [java.util Base64])) @@ -13,12 +14,7 @@ encoded-bytes)) (defn get-hostname [] - (let [env (System/getenv "ENVIRONMENT")] - (println "Current environment:" env) - (case env - "production" "https://sorter.social" - "staging" "https://staging.sorter.social" - "http://localhost:3000"))) + (util/get-base-url)) (defn get-origin-hostname [req] (let [origin (get-in req [:headers "origin"]) diff --git a/borter/src/app/spotify.clj b/borter/src/app/spotify.clj index 3e11713119141812fa2707ec956fb7ed612ee69a..b38d734351a1d4f1e142d93d4435ffe7bd20c02d 100644 --- a/borter/src/app/spotify.clj +++ b/borter/src/app/spotify.clj @@ -1,5 +1,6 @@ (ns app.spotify (:require [app.oauth :as oauth] + [app.util :as util] [hato.client :as hc] [clojure.data.json :as json] [ring.util.codec :as codec] @@ -47,10 +48,7 @@ (defn get-hostname [] - (case (System/getenv "ENVIRONMENT") - "production" "https://sorter.social" - "staging" "https://staging.sorter.social" - "http://localhost:3000")) + (util/get-base-url)) (defn create-spotify-tag "Creates a tag for a Spotify entity (artist, album, track) if it doesn't exist" diff --git a/borter/src/app/twitter.clj b/borter/src/app/twitter.clj index ef7b18fa1fcb82bb944b3035ffed44499181237f..b9a3fdccc15d13918a4d11d8c0443de94fd172b4 100644 --- a/borter/src/app/twitter.clj +++ b/borter/src/app/twitter.clj @@ -1,6 +1,7 @@ (ns app.twitter (:require [app.database :as db] [app.permissions :as perms] + [app.util :as util] [honey.sql.helpers :as h] [hato.client :as hc] [clojure.data.json :as json] @@ -37,9 +38,7 @@ (clojure.string/join "&" (map (fn [[k v]] (str (name k) "=" v)) params))) (defn get-hostname [] - (case (.getCanonicalHostName (java.net.InetAddress/getLocalHost)) - "sorter.isnt.online" "https://sorter.isnt.online/api/twitter/callback" - "http://localhost:3000/api/twitter/callback")) + (str (util/get-base-url) "/api/twitter/callback")) (defn encode-b64 [s] (.encodeToString (java.util.Base64/getEncoder) (.getBytes s))) diff --git a/borter/src/app/util.clj b/borter/src/app/util.clj index 384a64306c84aa8288ec44cd5de57edc248a826d..6a8aa0875accb28dc81bf57e645e3961b0a3ace5 100644 --- a/borter/src/app/util.clj +++ b/borter/src/app/util.clj @@ -2,6 +2,18 @@ (:require [clojure.string :as string]) (:import [java.net URLEncoder])) +(defn get-base-url + "Public site base URL for redirects and oauth callbacks." + [] + (if-let [hostname (not-empty (System/getenv "HOSTNAME"))] + (if (string/starts-with? hostname "http") + (string/replace hostname #"/$" "") + (str "https://" (string/replace hostname #"/$" ""))) + (case (or (System/getenv "ENVIRONMENT") "development") + "production" "https://sorter.social" + "staging" "https://staging.sorter.social" + "http://localhost:3000"))) + (defn urlencode-params [params] (clojure.string/join "&" (map (fn [[k v]] (str k "=" (URLEncoder/encode (str v) "UTF-8"))) params))) diff --git a/borter/src/app/youtube.clj b/borter/src/app/youtube.clj index 647ef7c6d4f2503a63a7c074d46dc815b2a23547..fc9a2f5ed516692f19e06b4c0221f510547cf8c0 100644 --- a/borter/src/app/youtube.clj +++ b/borter/src/app/youtube.clj @@ -6,6 +6,7 @@ [ring.util.response :as response] [app.database :as db] [app.permissions :as perms] + [app.util :as util] [honey.sql.helpers :as h] [sluj.core :refer [sluj]])) @@ -32,9 +33,7 @@ :body (json/read-str {:key-fn keyword}))) (defn get-hostname [] - (case (.getCanonicalHostName (java.net.InetAddress/getLocalHost)) - "localhost" "http://localhost:3000/api/youtube/callback" - "https://sorter.isnt.online/api/youtube/callback")) + (str (util/get-base-url) "/api/youtube/callback")) diff --git a/forter/src/utils/authUtils.js b/forter/src/utils/authUtils.js index 145e5db7ad6f7a6439d68c63beb4d07d31b2de08..98ed7fa671f9887f44dc1479d85569951eb4773e 100644 --- a/forter/src/utils/authUtils.js +++ b/forter/src/utils/authUtils.js @@ -5,8 +5,11 @@ import { current_session, fetchSession } from "../session"; let lastSyncTime = 0; const SYNC_THROTTLE_MS = 5000; // Only sync once every 5 seconds -// Get base URL based on Vite's mode +// Get base URL based on current origin, with build-mode fallbacks for SSR/build const getBaseUrl = () => { + if (typeof window !== 'undefined' && window.location?.origin) { + return window.location.origin; + } switch (import.meta.env.MODE) { case 'production': return 'https://sorter.social';