diff --git a/.env.example b/.env.example index df60d41e1..56a4e0016 100644 --- a/.env.example +++ b/.env.example @@ -47,15 +47,15 @@ RATE_LIMIT_MAX=100 # Max requests per IP # Base URLs -APP_BASE_URL=http://localhost:3000 -APP_SHORTCODE_BASE_URL=http://localhost:3000 -APP_ADMIN_URL=http://localhost:3100 +VITE_BASE_URL=http://localhost:3000 +VITE_SHORTCODE_BASE_URL=http://localhost:3000 +VITE_ADMIN_URL=http://localhost:3100 # Backend URLs -APP_BACKEND_GQL_URL=http://localhost:3170/graphql -APP_BACKEND_WS_URL=ws://localhost:3170/graphql -APP_BACKEND_API_URL=http://localhost:3170/v1 +VITE_BACKEND_GQL_URL=http://localhost:3170/graphql +VITE_BACKEND_WS_URL=ws://localhost:3170/graphql +VITE_BACKEND_API_URL=http://localhost:3170/v1 # Terms Of Service And Privacy Policy Links (Optional) -APP_APP_TOS_LINK=https://docs.hoppscotch.io/support/terms -APP_APP_PRIVACY_POLICY_LINK=https://docs.hoppscotch.io/support/privacy +VITE_APP_TOS_LINK=https://docs.hoppscotch.io/support/terms +VITE_APP_PRIVACY_POLICY_LINK=https://docs.hoppscotch.io/support/privacy diff --git a/aio_run.mjs b/aio_run.mjs index eadfeec5b..3c3538689 100644 --- a/aio_run.mjs +++ b/aio_run.mjs @@ -35,7 +35,7 @@ function runChildProcessWithPrefix(command, args, prefix) { } const envFileContent = Object.entries(process.env) - .filter(([env]) => env.startsWith("APP_")) + .filter(([env]) => env.startsWith("VITE_")) .map(([env, val]) => `${env}=${ (val.startsWith("\"") && val.endsWith("\"")) ? val diff --git a/packages/hoppscotch-backend/src/admin/admin.service.ts b/packages/hoppscotch-backend/src/admin/admin.service.ts index 9de865243..1ac4102ae 100644 --- a/packages/hoppscotch-backend/src/admin/admin.service.ts +++ b/packages/hoppscotch-backend/src/admin/admin.service.ts @@ -77,7 +77,7 @@ export class AdminService { template: 'code-your-own', variables: { inviteeEmail: inviteeEmail, - magicLink: `${process.env.APP_BASE_URL}`, + magicLink: `${process.env.VITE_BASE_URL}`, }, }); } catch (e) { diff --git a/packages/hoppscotch-backend/src/auth/auth.service.ts b/packages/hoppscotch-backend/src/auth/auth.service.ts index 9482962d7..63e59ac2a 100644 --- a/packages/hoppscotch-backend/src/auth/auth.service.ts +++ b/packages/hoppscotch-backend/src/auth/auth.service.ts @@ -95,9 +95,9 @@ export class AuthService { */ private async generateRefreshToken(userUid: string) { const refreshTokenPayload: RefreshTokenPayload = { - iss: process.env.APP_BASE_URL, + iss: process.env.VITE_BASE_URL, sub: userUid, - aud: [process.env.APP_BASE_URL], + aud: [process.env.VITE_BASE_URL], }; const refreshToken = await this.jwtService.sign(refreshTokenPayload, { @@ -127,9 +127,9 @@ export class AuthService { */ async generateAuthTokens(userUid: string) { const accessTokenPayload: AccessTokenPayload = { - iss: process.env.APP_BASE_URL, + iss: process.env.VITE_BASE_URL, sub: userUid, - aud: [process.env.APP_BASE_URL], + aud: [process.env.VITE_BASE_URL], }; const refreshToken = await this.generateRefreshToken(userUid); @@ -218,14 +218,14 @@ export class AuthService { let url: string; switch (origin) { case Origin.ADMIN: - url = process.env.APP_ADMIN_URL; + url = process.env.VITE_ADMIN_URL; break; case Origin.APP: - url = process.env.APP_BASE_URL; + url = process.env.VITE_BASE_URL; break; default: // if origin is invalid by default set URL to Hoppscotch-App - url = process.env.APP_BASE_URL; + url = process.env.VITE_BASE_URL; } await this.mailerService.sendEmail(email, { diff --git a/packages/hoppscotch-backend/src/team-invitation/team-invitation.service.ts b/packages/hoppscotch-backend/src/team-invitation/team-invitation.service.ts index f60bd8428..392d82e97 100644 --- a/packages/hoppscotch-backend/src/team-invitation/team-invitation.service.ts +++ b/packages/hoppscotch-backend/src/team-invitation/team-invitation.service.ts @@ -150,7 +150,7 @@ export class TeamInvitationService { template: 'team-invitation', variables: { invitee: creator.displayName ?? 'A Hoppscotch User', - action_url: `${process.env.APP_BASE_URL}/join-team?id=${dbInvitation.id}`, + action_url: `${process.env.VITE_BASE_URL}/join-team?id=${dbInvitation.id}`, invite_team_name: team.name, }, }); diff --git a/packages/hoppscotch-common/meta.ts b/packages/hoppscotch-common/meta.ts index e0a7e2fff..f7c58dd36 100644 --- a/packages/hoppscotch-common/meta.ts +++ b/packages/hoppscotch-common/meta.ts @@ -36,7 +36,7 @@ export const META_TAGS = (env: Record): IHTMLTag[] => [ }, { name: "image", - content: `${env.APP_BASE_URL}/banner.png`, + content: `${env.VITE_BASE_URL}/banner.png`, }, // Open Graph tags { @@ -49,7 +49,7 @@ export const META_TAGS = (env: Record): IHTMLTag[] => [ }, { name: "og:image", - content: `${env.APP_BASE_URL}/banner.png`, + content: `${env.VITE_BASE_URL}/banner.png`, }, // Twitter tags { @@ -74,7 +74,7 @@ export const META_TAGS = (env: Record): IHTMLTag[] => [ }, { name: "twitter:image", - content: `${env.APP_BASE_URL}/banner.png`, + content: `${env.VITE_BASE_URL}/banner.png`, }, // Add to homescreen for Chrome on Android. Fallback for PWA (handled by nuxt) { @@ -84,7 +84,7 @@ export const META_TAGS = (env: Record): IHTMLTag[] => [ // Windows phone tile icon { name: "msapplication-TileImage", - content: `${env.APP_BASE_URL}/icon.png`, + content: `${env.VITE_BASE_URL}/icon.png`, }, { name: "msapplication-TileColor", diff --git a/packages/hoppscotch-common/src/components/http/Request.vue b/packages/hoppscotch-common/src/components/http/Request.vue index 762dbea7b..39f99e373 100644 --- a/packages/hoppscotch-common/src/components/http/Request.vue +++ b/packages/hoppscotch-common/src/components/http/Request.vue @@ -485,7 +485,7 @@ const copyRequest = async () => { const copyShareLink = (shareLink: string) => { const link = `${ - import.meta.env.APP_SHORTCODE_BASE_URL ?? "https://hopp.sh" + import.meta.env.VITE_SHORTCODE_BASE_URL ?? "https://hopp.sh" }/r${shareLink}` if (navigator.share) { const time = new Date().toLocaleTimeString() diff --git a/packages/hoppscotch-common/src/components/profile/Shortcode.vue b/packages/hoppscotch-common/src/components/profile/Shortcode.vue index 82a092a7f..64b507a4f 100644 --- a/packages/hoppscotch-common/src/components/profile/Shortcode.vue +++ b/packages/hoppscotch-common/src/components/profile/Shortcode.vue @@ -106,7 +106,7 @@ const requestLabelColor = computed(() => const dateStamp = computed(() => shortDateTime(props.shortcode.createdOn)) const shortcodeBaseURL = - import.meta.env.APP_SHORTCODE_BASE_URL ?? "https://hopp.sh" + import.meta.env.VITE_SHORTCODE_BASE_URL ?? "https://hopp.sh" const copyShortcode = (codeID: string) => { copyToClipboard(`${shortcodeBaseURL}/r/${codeID}`) diff --git a/packages/hoppscotch-common/src/helpers/backend/GQLClient.ts b/packages/hoppscotch-common/src/helpers/backend/GQLClient.ts index dc5948411..15a1c420a 100644 --- a/packages/hoppscotch-common/src/helpers/backend/GQLClient.ts +++ b/packages/hoppscotch-common/src/helpers/backend/GQLClient.ts @@ -28,9 +28,9 @@ import { platform } from "~/platform" // TODO: Implement caching const BACKEND_GQL_URL = - import.meta.env.APP_BACKEND_GQL_URL ?? "https://api.hoppscotch.io/graphql" + import.meta.env.VITE_BACKEND_GQL_URL ?? "https://api.hoppscotch.io/graphql" const BACKEND_WS_URL = - import.meta.env.APP_BACKEND_WS_URL ?? "wss://api.hoppscotch.io/graphql" + import.meta.env.VITE_BACKEND_WS_URL ?? "wss://api.hoppscotch.io/graphql" type GQLOpType = "query" | "mutation" | "subscription" /** diff --git a/packages/hoppscotch-common/src/helpers/strategies/AxiosStrategy.ts b/packages/hoppscotch-common/src/helpers/strategies/AxiosStrategy.ts index 8c8bce728..137bc6592 100644 --- a/packages/hoppscotch-common/src/helpers/strategies/AxiosStrategy.ts +++ b/packages/hoppscotch-common/src/helpers/strategies/AxiosStrategy.ts @@ -29,7 +29,7 @@ const getProxyPayload = ( let payload: ProxyPayloadType = { ...req, wantsBinary: true, - accessToken: import.meta.env.APP_PROXYSCOTCH_ACCESS_TOKEN ?? "", + accessToken: import.meta.env.VITE_PROXYSCOTCH_ACCESS_TOKEN ?? "", } if (payload.data instanceof FormData) { diff --git a/packages/hoppscotch-common/src/modules/sentry.ts b/packages/hoppscotch-common/src/modules/sentry.ts index aad744e80..bf8a096de 100644 --- a/packages/hoppscotch-common/src/modules/sentry.ts +++ b/packages/hoppscotch-common/src/modules/sentry.ts @@ -52,17 +52,17 @@ function initSentry(dsn: string, router: Router, app: App) { Sentry.init({ app, dsn, - release: import.meta.env.APP_SENTRY_RELEASE_TAG ?? undefined, + release: import.meta.env.VITE_SENTRY_RELEASE_TAG ?? undefined, environment: APP_IS_IN_DEV_MODE ? "dev" - : import.meta.env.APP_SENTRY_ENVIRONMENT, + : import.meta.env.VITE_SENTRY_ENVIRONMENT, integrations: [ new BrowserTracing({ routingInstrumentation: Sentry.vueRouterInstrumentation( getInstrumentationVueRouter(router) ), // TODO: We may want to limit this later on - tracingOrigins: [new URL(import.meta.env.APP_BACKEND_GQL_URL).origin], + tracingOrigins: [new URL(import.meta.env.VITE_BACKEND_GQL_URL).origin], }), ], tracesSampleRate: 0.8, @@ -175,22 +175,22 @@ function subscribeForAppDataTags() { export default { onRouterInit(app, router) { - if (!import.meta.env.APP_SENTRY_DSN) { + if (!import.meta.env.VITE_SENTRY_DSN) { console.log( - "Sentry tracing is not enabled because 'APP_SENTRY_DSN' env is not defined" + "Sentry tracing is not enabled because 'VITE_SENTRY_DSN' env is not defined" ) return } if (settingsStore.value.TELEMETRY_ENABLED) { - initSentry(import.meta.env.APP_SENTRY_DSN, router, app) + initSentry(import.meta.env.VITE_SENTRY_DSN, router, app) } settingsStore.subject$.subscribe(({ TELEMETRY_ENABLED }) => { if (!TELEMETRY_ENABLED && sentryActive) { deinitSentry() } else if (TELEMETRY_ENABLED && !sentryActive) { - initSentry(import.meta.env.APP_SENTRY_DSN!, router, app) + initSentry(import.meta.env.VITE_SENTRY_DSN!, router, app) } }) diff --git a/packages/hoppscotch-common/src/vite-envs.d.ts b/packages/hoppscotch-common/src/vite-envs.d.ts index 04ccdaabd..5b8a2ed45 100644 --- a/packages/hoppscotch-common/src/vite-envs.d.ts +++ b/packages/hoppscotch-common/src/vite-envs.d.ts @@ -2,30 +2,30 @@ // Environment Variables Intellisense interface ImportMetaEnv { - readonly APP_GA_ID: string + readonly VITE_GA_ID: string - readonly APP_GTM_ID: string + readonly VITE_GTM_ID: string - readonly APP_API_KEY: string - readonly APP_AUTH_DOMAIN: string - readonly APP_DATABASE_URL: string - readonly APP_PROJECT_ID: string - readonly APP_STORAGE_BUCKET: string - readonly APP_MESSAGING_SENDER_ID: string - readonly APP_APP_ID: string - readonly APP_MEASUREMENT_ID: string + readonly VITE_API_KEY: string + readonly VITE_AUTH_DOMAIN: string + readonly VITE_DATABASE_URL: string + readonly VITE_PROJECT_ID: string + readonly VITE_STORAGE_BUCKET: string + readonly VITE_MESSAGING_SENDER_ID: string + readonly VITE_APP_ID: string + readonly VITE_MEASUREMENT_ID: string - readonly APP_BASE_URL: string - readonly APP_SHORTCODE_BASE_URL: string + readonly VITE_BASE_URL: string + readonly VITE_SHORTCODE_BASE_URL: string - readonly APP_BACKEND_GQL_URL: string - readonly APP_BACKEND_WS_URL: string + readonly VITE_BACKEND_GQL_URL: string + readonly VITE_BACKEND_WS_URL: string - readonly APP_SENTRY_DSN?: string - readonly APP_SENTRY_ENVIRONMENT?: string - readonly APP_SENTRY_RELEASE_TAG?: string + readonly VITE_SENTRY_DSN?: string + readonly VITE_SENTRY_ENVIRONMENT?: string + readonly VITE_SENTRY_RELEASE_TAG?: string - readonly APP_PROXYSCOTCH_ACCESS_TOKEN?: string + readonly VITE_PROXYSCOTCH_ACCESS_TOKEN?: string } interface ImportMeta { diff --git a/packages/hoppscotch-selfhost-web/prod_run.mjs b/packages/hoppscotch-selfhost-web/prod_run.mjs index f9a4713b7..57a68a778 100755 --- a/packages/hoppscotch-selfhost-web/prod_run.mjs +++ b/packages/hoppscotch-selfhost-web/prod_run.mjs @@ -3,7 +3,7 @@ import { execSync } from "child_process" import fs from "fs" const envFileContent = Object.entries(process.env) - .filter(([env]) => env.startsWith("APP_")) + .filter(([env]) => env.startsWith("VITE_")) .map( ([env, val]) => `${env}=${val.startsWith('"') && val.endsWith('"') ? val : `"${val}"`}` diff --git a/packages/hoppscotch-selfhost-web/src/platform/auth.ts b/packages/hoppscotch-selfhost-web/src/platform/auth.ts index 11324267d..e95925cb0 100644 --- a/packages/hoppscotch-selfhost-web/src/platform/auth.ts +++ b/packages/hoppscotch-selfhost-web/src/platform/auth.ts @@ -17,21 +17,23 @@ const currentUser$ = new BehaviorSubject(null) export const probableUser$ = new BehaviorSubject(null) async function logout() { - await axios.get(`${import.meta.env.APP_BACKEND_API_URL}/auth/logout`, { + await axios.get(`${import.meta.env.VITE_BACKEND_API_URL}/auth/logout`, { withCredentials: true, }) } async function signInUserWithGithubFB() { - window.location.href = `${import.meta.env.APP_BACKEND_API_URL}/auth/github` + window.location.href = `${import.meta.env.VITE_BACKEND_API_URL}/auth/github` } async function signInUserWithGoogleFB() { - window.location.href = `${import.meta.env.APP_BACKEND_API_URL}/auth/google` + window.location.href = `${import.meta.env.VITE_BACKEND_API_URL}/auth/google` } async function signInUserWithMicrosoftFB() { - window.location.href = `${import.meta.env.APP_BACKEND_API_URL}/auth/microsoft` + window.location.href = `${ + import.meta.env.VITE_BACKEND_API_URL + }/auth/microsoft` } async function getInitialUserDetails() { @@ -51,7 +53,7 @@ async function getInitialUserDetails() { message: string }> }>( - `${import.meta.env.APP_BACKEND_GQL_URL}`, + `${import.meta.env.VITE_BACKEND_GQL_URL}`, { query: `query Me { me { @@ -145,7 +147,7 @@ async function setInitialUser() { async function refreshToken() { const res = await axios.get( - `${import.meta.env.APP_BACKEND_API_URL}/auth/refresh`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/refresh`, { withCredentials: true, } @@ -164,7 +166,7 @@ async function refreshToken() { async function sendMagicLink(email: string) { const res = await axios.post( - `${import.meta.env.APP_BACKEND_API_URL}/auth/signin`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/signin`, { email, }, @@ -282,7 +284,7 @@ export const def: AuthPlatformDef = { const deviceIdentifier = getLocalConfig("deviceIdentifier") await axios.post( - `${import.meta.env.APP_BACKEND_API_URL}/auth/verify`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/verify`, { token: token, deviceIdentifier, diff --git a/packages/hoppscotch-selfhost-web/vite.config.ts b/packages/hoppscotch-selfhost-web/vite.config.ts index 8e4f66e85..e26605e0a 100644 --- a/packages/hoppscotch-selfhost-web/vite.config.ts +++ b/packages/hoppscotch-selfhost-web/vite.config.ts @@ -19,9 +19,10 @@ import Unfonts from "unplugin-fonts/vite" import legacy from "@vitejs/plugin-legacy" import ImportMetaEnv from "@import-meta-env/unplugin" -const ENV = loadEnv("development", path.resolve(__dirname, "../../"), ["APP_"]) +const ENV = loadEnv("development", path.resolve(__dirname, "../../"), ["VITE_"]) export default defineConfig({ + envPrefix: process.env.HOPP_ALLOW_RUNTIME_ENV ? "VITE_BUILDTIME_" : "VITE_", envDir: path.resolve(__dirname, "../../"), // TODO: Migrate @hoppscotch/data to full ESM define: { @@ -85,7 +86,7 @@ export default defineConfig({ nuxtStyle: true, allowRobots: true, dest: ".sitemap-gen", - hostname: ENV.APP_BASE_URL, + hostname: ENV.VITE_BASE_URL, }) }, }), diff --git a/packages/hoppscotch-sh-admin/prod_run.mjs b/packages/hoppscotch-sh-admin/prod_run.mjs index da7297098..9e386cb98 100755 --- a/packages/hoppscotch-sh-admin/prod_run.mjs +++ b/packages/hoppscotch-sh-admin/prod_run.mjs @@ -3,7 +3,7 @@ import { execSync } from "child_process" import fs from "fs" const envFileContent = Object.entries(process.env) - .filter(([env]) => env.startsWith("APP_")) + .filter(([env]) => env.startsWith("VITE_")) .map(([env, val]) => `${env}=${ (val.startsWith("\"") && val.endsWith("\"")) ? val diff --git a/packages/hoppscotch-sh-admin/src/helpers/auth.ts b/packages/hoppscotch-sh-admin/src/helpers/auth.ts index 8aba7f3c0..ba7385dbe 100644 --- a/packages/hoppscotch-sh-admin/src/helpers/auth.ts +++ b/packages/hoppscotch-sh-admin/src/helpers/auth.ts @@ -55,27 +55,27 @@ const currentUser$ = new BehaviorSubject(null); export const probableUser$ = new BehaviorSubject(null); async function logout() { - await axios.get(`${import.meta.env.APP_BACKEND_API_URL}/auth/logout`, { + await axios.get(`${import.meta.env.VITE_BACKEND_API_URL}/auth/logout`, { withCredentials: true, }); } async function signInUserWithGithubFB() { window.location.href = `${ - import.meta.env.APP_BACKEND_API_URL - }/auth/github?redirect_uri=${import.meta.env.APP_ADMIN_URL}`; + import.meta.env.VITE_BACKEND_API_URL + }/auth/github?redirect_uri=${import.meta.env.VITE_ADMIN_URL}`; } async function signInUserWithGoogleFB() { window.location.href = `${ - import.meta.env.APP_BACKEND_API_URL - }/auth/google?redirect_uri=${import.meta.env.APP_ADMIN_URL}`; + import.meta.env.VITE_BACKEND_API_URL + }/auth/google?redirect_uri=${import.meta.env.VITE_ADMIN_URL}`; } async function signInUserWithMicrosoftFB() { window.location.href = `${ - import.meta.env.APP_BACKEND_API_URL - }/auth/microsoft?redirect_uri=${import.meta.env.APP_ADMIN_URL}`; + import.meta.env.VITE_BACKEND_API_URL + }/auth/microsoft?redirect_uri=${import.meta.env.VITE_ADMIN_URL}`; } async function getInitialUserDetails() { @@ -95,7 +95,7 @@ async function getInitialUserDetails() { message: string; }>; }>( - `${import.meta.env.APP_BACKEND_GQL_URL}`, + `${import.meta.env.VITE_BACKEND_GQL_URL}`, { query: `query Me { me { @@ -189,7 +189,7 @@ async function setInitialUser() { async function refreshToken() { const res = await axios.get( - `${import.meta.env.APP_BACKEND_API_URL}/auth/refresh`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/refresh`, { withCredentials: true, } @@ -208,7 +208,7 @@ async function refreshToken() { async function elevateUser() { const res = await axios.get( - `${import.meta.env.APP_BACKEND_API_URL}/auth/verify/admin`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/verify/admin`, { withCredentials: true, } @@ -219,7 +219,7 @@ async function elevateUser() { async function sendMagicLink(email: string) { const res = await axios.post( - `${import.meta.env.APP_BACKEND_API_URL}/auth/signin?origin=admin`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/signin?origin=admin`, { email, }, @@ -337,7 +337,7 @@ export const auth = { const deviceIdentifier = getLocalConfig('deviceIdentifier'); await axios.post( - `${import.meta.env.APP_BACKEND_API_URL}/auth/verify`, + `${import.meta.env.VITE_BACKEND_API_URL}/auth/verify`, { token: token, deviceIdentifier, @@ -383,7 +383,7 @@ export const auth = { await this.signInWithEmailLink(deviceIdentifier, window.location.href); removeLocalConfig('deviceIdentifier'); - window.location.href = import.meta.env.APP_ADMIN_URL; + window.location.href = import.meta.env.VITE_ADMIN_URL; } }, }; diff --git a/packages/hoppscotch-sh-admin/src/main.ts b/packages/hoppscotch-sh-admin/src/main.ts index 85257a6e8..4fdccd817 100644 --- a/packages/hoppscotch-sh-admin/src/main.ts +++ b/packages/hoppscotch-sh-admin/src/main.ts @@ -20,7 +20,7 @@ import { auth } from './helpers/auth'; const app = createApp(App).use( urql, createClient({ - url: import.meta.env.APP_BACKEND_GQL_URL, + url: import.meta.env.VITE_BACKEND_GQL_URL, requestPolicy: 'network-only', fetchOptions: () => { return { diff --git a/packages/hoppscotch-sh-admin/vite.config.ts b/packages/hoppscotch-sh-admin/vite.config.ts index e09e3d50e..9bea4bf32 100644 --- a/packages/hoppscotch-sh-admin/vite.config.ts +++ b/packages/hoppscotch-sh-admin/vite.config.ts @@ -14,6 +14,10 @@ import ImportMetaEnv from "@import-meta-env/unplugin" // https://vitejs.dev/config/ export default defineConfig({ + envPrefix: + process.env.HOPP_ALLOW_RUNTIME_ENV + ? "VITE_BUILDTIME_" + : "VITE_", server: { port: 3100, }, diff --git a/prod.Dockerfile b/prod.Dockerfile index b6dcf09b7..6fc5da7bf 100644 --- a/prod.Dockerfile +++ b/prod.Dockerfile @@ -2,6 +2,8 @@ FROM node:18-bookworm as base_builder WORKDIR /usr/src/app +ENV HOPP_ALLOW_RUNTIME_ENV=true + RUN npm install -g pnpm COPY pnpm-lock.yaml . RUN pnpm fetch