Skip to content

Commit 6d15244

Browse files
jake-lowCollinBeczak
authored andcommitted
Use a local proxy in dev mode
1 parent dffb269 commit 6d15244

6 files changed

Lines changed: 47 additions & 11 deletions

File tree

‎.env.example‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
VITE_APP_NAME="MapRoulette"
22
VITE_APP_DESCRIPTION="MapRoulette 4 Local Development Environment"
33
VITE_API_BASE_URL="https://maproulette.org"
4-
VITE_MAP_ROULETTE_SERVER_WEBSOCKET_URL="wss://maproulette.org/ws"
54
VITE_SERVER_API_KEY=""
65
# Base URL for short links embedded in OSM changeset comments
76
# (e.g. https://mpr.lt/c/<challengeId>/t/<taskId>). If unset,

‎.env.test‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ VITE_APP_DESCRIPTION="MapRoulette E2E test environment"
33
VITE_APP_URL="http://localhost:3005"
44

55
VITE_API_BASE_URL="http://localhost:9000"
6-
VITE_MAP_ROULETTE_SERVER_WEBSOCKET_URL="ws://localhost:9000/ws"

‎src/api/client.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import ky from 'ky'
22

33
export const apiKey = window.env.VITE_SERVER_API_KEY
4+
export const apiBaseUrl = window.env.VITE_API_BASE_URL || 'http://127.0.0.1:9000'
45

56
export const apiRequest = ky.extend({
6-
prefixUrl: window.env.VITE_API_BASE_URL || 'http://127.0.0.1:9000',
7+
prefixUrl: apiBaseUrl,
78
credentials: 'include',
89
timeout: 60000,
910
retry: {

‎src/contexts/WebSocketContext.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ReactNode } from 'react'
22
import { createContext, useCallback, useContext, useEffect, useMemo } from 'react'
33
import useWebSocketHook, { ReadyState } from 'react-use-websocket'
4+
import { apiBaseUrl } from '@/api/client'
45
import { wsLogger } from '@/lib/logger'
56
import type { WebSocketMessageTypes } from '@/types/WebSocket'
67
import { useAuthContext } from './AuthContext'
@@ -18,7 +19,7 @@ export const WebSocketProvider = ({ children }: { children: ReactNode }) => {
1819
const { user } = useAuthContext()
1920

2021
const { lastMessage, readyState, sendMessage } = useWebSocketHook(
21-
user ? import.meta.env.VITE_MAP_ROULETTE_SERVER_WEBSOCKET_URL : null,
22+
user ? `${apiBaseUrl.replace(/^http/, 'ws').replace(/\/$/, '')}/ws` : null,
2223
{
2324
shouldReconnect: () => user !== null,
2425
reconnectAttempts: 10,

‎src/vite-env.d.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ interface AppEnv {
1111
readonly VITE_APP_NAME: string
1212
readonly VITE_APP_DESCRIPTION: string
1313
readonly VITE_API_BASE_URL: string | undefined
14-
readonly VITE_MAP_ROULETTE_SERVER_WEBSOCKET_URL: string
1514
readonly VITE_SERVER_API_KEY: string | undefined
1615
readonly VITE_APP_URL: string | undefined
1716
readonly VITE_OSM_SERVER: string | undefined

‎vite.config.ts‎

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import tailwindcss from '@tailwindcss/vite'
88
import { tanstackRouter } from '@tanstack/router-plugin/vite'
99
import viteReact from '@vitejs/plugin-react'
1010
import { playwright } from '@vitest/browser-playwright'
11-
import { loadEnv, type Plugin } from 'vite'
11+
import { loadEnv, type Plugin, type ProxyOptions } from 'vite'
1212
import svgr from 'vite-plugin-svgr'
1313
import { defineConfig } from 'vitest/config'
1414

@@ -73,26 +73,63 @@ const TESTED_TSX_FILES = [
7373
// local .env file. For release builds, env.json is written to dist/ and contains
7474
// defaults (from .env.example) which can be overridden at deploy time (e.g. via
7575
// env vars on the Docker container; see docker/90-write-env-to-json.sh)
76+
//
77+
// In dev mode the backend is proxied through the dev server, and env.json points
78+
// VITE_API_BASE_URL at the dev server itself. This keeps the backend's session
79+
// cookie first-party, which a SameSite=Lax cookie needs when the backend is
80+
// remote (e.g. developing against production).
7681
function runtimeEnv(): Plugin {
77-
let json: string
82+
let env: Record<string, string>
7883
return {
7984
name: 'maproulette:runtime-env',
80-
configResolved(config) {
81-
json = JSON.stringify(loadEnv(config.mode, config.root, 'VITE_'), null, 2)
85+
config(config, { mode, command }) {
86+
env = loadEnv(mode, resolve(config.root ?? process.cwd()), 'VITE_')
87+
if (command !== 'serve') return
88+
const target = env.VITE_API_BASE_URL || 'http://127.0.0.1:9000'
89+
const http: ProxyOptions = {
90+
target,
91+
changeOrigin: true,
92+
cookieDomainRewrite: '',
93+
configure: (proxy) => {
94+
// The backend derives the OAuth redirect_uri from Origin, falling
95+
// back to its configured frontend. Browsers omit Origin on
96+
// same-origin GETs, so supply the dev server's.
97+
proxy.on('proxyReq', (proxyReq, req) => {
98+
if (!req.headers.origin) proxyReq.setHeader('origin', `http://${req.headers.host}`)
99+
})
100+
// The dev server is plain http, where browsers may drop Secure cookies.
101+
proxy.on('proxyRes', (res) => {
102+
res.headers['set-cookie'] = res.headers['set-cookie']?.map((c) =>
103+
c.replace(/;\s*Secure/i, '')
104+
)
105+
})
106+
},
107+
}
108+
return {
109+
server: {
110+
proxy: {
111+
'/api': http,
112+
'/auth': http,
113+
'/ws': { target, changeOrigin: true, ws: true },
114+
},
115+
},
116+
}
82117
},
83118
configureServer(server) {
84119
server.middlewares.use((req, res, next) => {
85120
if (req.url !== '/env.json') return next()
86121
res.setHeader('Content-Type', 'application/json')
87122
res.setHeader('Cache-Control', 'no-store')
88-
res.end(json)
123+
res.end(
124+
JSON.stringify({ ...env, VITE_API_BASE_URL: `http://${req.headers.host}` }, null, 2)
125+
)
89126
})
90127
},
91128
generateBundle() {
92129
this.emitFile({
93130
type: 'asset',
94131
fileName: 'env.json',
95-
source: json,
132+
source: JSON.stringify(env, null, 2),
96133
})
97134
},
98135
}

0 commit comments

Comments
 (0)