Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
80525f0
mv found API keys to .env
AnilKumar3494 Feb 21, 2026
9aac547
all hardcoded ones are verfided and moved
AnilKumar3494 Feb 21, 2026
b6e95d7
final mv
AnilKumar3494 Feb 25, 2026
c7d9b10
mv verification pwd
AnilKumar3494 Feb 25, 2026
c5c530e
mv verification pwd
AnilKumar3494 Feb 25, 2026
cd52af8
add missing msg
AnilKumar3494 Mar 2, 2026
74b8a0b
moe yelling
AnilKumar3494 Mar 2, 2026
8ad514c
added yelling in dev env for all keys and imports if missing
AnilKumar3494 Mar 2, 2026
2ca51bf
add: secerts workflow to test injections
AnilKumar3494 Mar 7, 2026
bf8ec0b
Merge branch 'develop' into update-env
AnilKumar3494 Mar 7, 2026
506b34c
add: secerts workflow to test injections
AnilKumar3494 Mar 7, 2026
ebc392f
should work -- clean up after
AnilKumar3494 Mar 7, 2026
69ef167
another try to make it work -- clean up after
AnilKumar3494 Mar 7, 2026
3c5652d
another try to make it work -- clean up after
AnilKumar3494 Mar 7, 2026
ca3c34b
try 4 to make it work -- clean up after
AnilKumar3494 Mar 7, 2026
fb7d2fb
try 5 to make it work -- clean up after
AnilKumar3494 Mar 7, 2026
9010d32
try 6 to make it work -- clean up after
AnilKumar3494 Mar 7, 2026
dc7fee3
try 7 debug missing key ugg
AnilKumar3494 Mar 7, 2026
2fb5fec
try 7 debug missing key ugg
AnilKumar3494 Mar 7, 2026
1897422
try 8 should work
AnilKumar3494 Mar 7, 2026
a447e9f
working cleaup done
AnilKumar3494 Mar 7, 2026
a4d16e2
testing something -- need to add more secret keys
AnilKumar3494 Mar 7, 2026
5c451eb
just need to add one more key to GH secrets and should work
AnilKumar3494 Mar 7, 2026
96ab60f
zod env config
AnilKumar3494 Mar 14, 2026
fd9fb46
zod env config
AnilKumar3494 Mar 14, 2026
1fd809f
Update config.ts
AnilKumar3494 Mar 14, 2026
cc89900
simplfy
AnilKumar3494 Mar 19, 2026
d5f20fb
Adds vite preflight check to ensure environment variables are set and…
gcardonag Mar 24, 2026
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
5 changes: 5 additions & 0 deletions .github/workflows/betasite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
env:
AWS_DEFAULT_REGION: us-east-2
VITE_DB_URL: https://wantycfbnzzocsbthqzs.supabase.co
VITE_DB_API_KEY: ${{ secrets.SUPABASE_API_KEY }}
VITE_REACT_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_GOOGLE_MAPS_API_KEY }}
VITE_OPEN_ROUTE_SERVICE_API_KEY: ${{ secrets.OPEN_ROUTE_SERVICE_API_KEY }}
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
VITE_VERIFICATION_PASSWORD: ${{ secrets.VERIFICATION_PASSWORD }}
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/build_testsite.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
name: Deploy Test Site on S3

on: [workflow_call]
env:
AWS_DEFAULT_REGION: us-east-2

jobs:
build:
runs-on: ubuntu-latest
env:
AWS_DEFAULT_REGION: us-east-2
VITE_DB_URL: https://wantycfbnzzocsbthqzs.supabase.co
VITE_DB_API_KEY: ${{ secrets.SUPABASE_API_KEY }}
VITE_REACT_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_GOOGLE_MAPS_API_KEY }}
VITE_OPEN_ROUTE_SERVICE_API_KEY: ${{ secrets.OPEN_ROUTE_SERVICE_API_KEY }}
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
VITE_VERIFICATION_PASSWORD: ${{ secrets.VERIFICATION_PASSWORD }}
steps:
- uses: actions/checkout@v1
- name: Configure AWS Credentials
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/cypress_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ on: [workflow_call]

jobs:
cypress_tests:
runs-on: ubuntu-latest
env:
VITE_DB_URL: https://wantycfbnzzocsbthqzs.supabase.co
VITE_DB_API_KEY: ${{ secrets.SUPABASE_API_KEY }}
VITE_REACT_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_GOOGLE_MAPS_API_KEY }}
VITE_OPEN_ROUTE_SERVICE_API_KEY: ${{ secrets.OPEN_ROUTE_SERVICE_API_KEY }}
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
VITE_VERIFICATION_PASSWORD: ${{ secrets.VERIFICATION_PASSWORD }}
strategy:
matrix:
include:
Expand All @@ -13,7 +21,6 @@ jobs:
- spec: 'cypress/e2e/mobile/*.cy.ts'
config_file: 'cypress.mobile.config.ts'
video_path: 'cypress/videos/mobile'
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v6
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lighthouse_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ on: [workflow_call]
env:
AWS_DEFAULT_REGION: us-east-2
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout

jobs:
lighthouse-check:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/prodsite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
env:
AWS_DEFAULT_REGION: us-east-2
VITE_DB_URL: https://wantycfbnzzocsbthqzs.supabase.co
VITE_DB_API_KEY: ${{ secrets.SUPABASE_API_KEY }}
VITE_REACT_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_GOOGLE_MAPS_API_KEY }}
VITE_OPEN_ROUTE_SERVICE_API_KEY: ${{ secrets.OPEN_ROUTE_SERVICE_API_KEY }}
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
VITE_VERIFICATION_PASSWORD: ${{ secrets.VERIFICATION_PASSWORD }}
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/testsite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ jobs:
secrets: inherit
cypress-testing:
uses: ./.github/workflows/cypress_testing.yml
secrets: inherit
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ services:
environment:
CI: 'false'
VITE_DB_URL:
VITE_DB_API_KEY:
VITE_REACT_GOOGLE_MAPS_API_KEY:
VITE_OPEN_ROUTE_SERVICE_API_KEY:
Comment thread
AnilKumar3494 marked this conversation as resolved.
VITE_PUBLIC_POSTHOG_KEY:
VITE_VERIFICATION_PASSWORD:
volumes:
- './docker/build:/usr/src/app/build'
- './docker/testResults:/usr/src/app/testResults'
8 changes: 8 additions & 0 deletions src/.example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Below is how your .env file should look. Make sure to replace the placeholder values with your actual API keys.
# To get these details please message us in the #phlask-data channel on Slack

VITE_DB_API_KEY=db_api_key_here
VITE_REACT_GOOGLE_MAPS_API_KEY=google_maps_api_key_here
VITE_OPEN_ROUTE_SERVICE_API_KEY=open_route_service_api_key_here
VITE_PUBLIC_POSTHOG_KEY=posthog_api_key_here
VITE_VERIFICATION_PASSWORD=verification_password_here
15 changes: 6 additions & 9 deletions src/components/Providers/AnalyticsProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { PostHogProvider } from 'posthog-js/react';
import type { PropsWithChildren } from 'react';
import { env } from 'config';

const APIHOST = 'https://us.i.posthog.com';
const APIKEY = env.VITE_PUBLIC_POSTHOG_KEY;

const postHogOptions = {
api_host:
import.meta.env.VITE_PUBLIC_POSTHOG_HOST || 'https://us.i.posthog.com',
api_host: APIHOST,
mask_all_text: true
};

Expand All @@ -17,13 +20,7 @@ const AnalyticsProvider = ({ children }: PropsWithChildren) => {
return children;

return (
<PostHogProvider
apiKey={
import.meta.env.VITE_PUBLIC_POSTHOG_KEY ||
'phc_I0pbyDLZ2ifEgaQaum7vDVkqmwSrLle3SHbNi8tgwpY'
}
options={postHogOptions}
>
<PostHogProvider apiKey={APIKEY} options={postHogOptions}>
{children}
</PostHogProvider>
);
Expand Down
32 changes: 17 additions & 15 deletions src/components/Providers/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ import type { PropsWithChildren } from 'react';
import ToolbarContextProvider from './ToolbarContextProvider';
import queryClient from 'services/queryClient';
import ThemeProvider from './ThemeProvider';
import { env } from 'config';

const Providers = ({ children }: PropsWithChildren) => (
<QueryClientProvider client={queryClient}>
<APIProvider
apiKey="AIzaSyABw5Fg78SgvedyHr8tl-tPjcn5iFotB6I"
libraries={['places']}
>
<ToolbarContextProvider>
<ThemeProvider>
<CssBaseline />
{children}
</ThemeProvider>
</ToolbarContextProvider>
</APIProvider>
</QueryClientProvider>
);
const REACT_GOOGLE_MAPS_API_KEY = env.VITE_REACT_GOOGLE_MAPS_API_KEY;

const Providers = ({ children }: PropsWithChildren) => {
return (
<QueryClientProvider client={queryClient}>
<APIProvider apiKey={REACT_GOOGLE_MAPS_API_KEY} libraries={['places']}>
<ToolbarContextProvider>
<ThemeProvider>
<CssBaseline />
{children}
</ThemeProvider>
</ToolbarContextProvider>
</APIProvider>
</QueryClientProvider>
);
};

export default Providers;
3 changes: 2 additions & 1 deletion src/components/Verification/VerificationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import Dialog from '@mui/material/Dialog';
import { updateResource } from 'services/db';
import type { ResourceEntry, Verification } from 'types/ResourceEntry';
import useSelectedResource from 'hooks/useSelectedResource';
import { env } from 'config';

const PASSWORD = 'ZnJlZXdhdGVy'; // Ask in Slack if you want the real password
const PASSWORD = env.VITE_VERIFICATION_PASSWORD;

type VerificationButtonProps = {
resource: ResourceEntry;
Expand Down
20 changes: 20 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { z } from 'zod';

const envSchema = z.object({
VITE_DB_API_KEY: z.string().min(1),
VITE_REACT_GOOGLE_MAPS_API_KEY: z.string().min(1),
VITE_OPEN_ROUTE_SERVICE_API_KEY: z.string().min(1),
VITE_PUBLIC_POSTHOG_KEY: z.string().min(1),
VITE_VERIFICATION_PASSWORD: z.string().min(1)
});

const result = envSchema.safeParse(import.meta.env);

if (!result.success) {
console.error(result.error);
throw new Error(
`Environment variables are missing or invalid in your .env file. Check the error details above.`
);
}

export const env = result.data;
6 changes: 2 additions & 4 deletions src/hooks/queries/useWalkingDurationQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import type { ResourceEntry } from 'types/ResourceEntry';
import getUserLocation from 'utils/getUserLocation';
import useActiveSearchLocation from 'hooks/useActiveSearchLocation';

const OPEN_ROUTE_SERVICE_API_KEY =
'5b3ce3597851110001cf6248ac903cdbe0364ca9850aa85cb64d8dfc';
import { env } from 'config';

const BASE_URL = 'https://api.openrouteservice.org/v2';
const PATH = '/directions/foot-walking';
Expand Down Expand Up @@ -77,7 +75,7 @@ export const useWalkingDurationQuery = ({
const endingLocation = [longitude, latitude].join(',');

const params = new URLSearchParams({
api_key: OPEN_ROUTE_SERVICE_API_KEY,
api_key: env.VITE_OPEN_ROUTE_SERVICE_API_KEY,
start: startingLocation,
end: endingLocation
});
Expand Down
20 changes: 11 additions & 9 deletions src/services/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { createClient } from '@supabase/supabase-js';
import type { Provider, ResourceEntry } from 'types/ResourceEntry';
import type { ResourceTypeOption } from 'hooks/useResourceType';
import type { Contributor } from 'types/Contributor';
import { env } from 'config';

// Need access to the database? Message us in the #phlask-data channel on Slack
const databaseUrl =
import.meta.env?.VITE_DB_URL || 'https://wantycfbnzzocsbthqzs.supabase.co';
// Need access to the database? Please refer to .example.env and message us in the #phlask-data channel on Slack
const databaseUrl = 'https://wantycfbnzzocsbthqzs.supabase.co';
const databaseApiKey = env.VITE_DB_API_KEY;
const resourceDatabaseName = 'resources';
const databaseApiKey =
import.meta.env?.VITE_DB_API_KEY ||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6IndhbnR5Y2Zibnp6b2NzYnRocXpzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzcwNDY2OTgsImV4cCI6MjA1MjYyMjY5OH0.yczsMOx3Y-zsWu-GjYEajIb0yw9fYWEIUglmmfM1zCY';
const contributorDatabaseName = 'airtable_contributors';
const providersDatabaseName = 'providers';

Expand Down Expand Up @@ -127,11 +125,15 @@ export const getContributors = async (): Promise<Contributor[]> => {
return data;
};

export const getResourceProviders = async (resourceId: string): Promise<Provider[]> => {
export const getResourceProviders = async (
resourceId: string
): Promise<Provider[]> => {
const { data, error } = await supabase
.from(providersDatabaseName)
.select('name, logo_url, url:website_url, resource_providers!inner(resource_id)')
.eq('resource_providers.resource_id', resourceId)
.select(
'name, logo_url, url:website_url, resource_providers!inner(resource_id)'
)
.eq('resource_providers.resource_id', resourceId);
if (error) {
throw error;
}
Expand Down
55 changes: 55 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,69 @@
import { defineConfig } from 'vite';
import type { Plugin } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';

const REQUIRED_ENV_VARS = [
'VITE_DB_API_KEY',
'VITE_REACT_GOOGLE_MAPS_API_KEY',
'VITE_OPEN_ROUTE_SERVICE_API_KEY',
'VITE_PUBLIC_POSTHOG_KEY',
'VITE_VERIFICATION_PASSWORD',
];

function envCheckPlugin(): Plugin {
let missingVars: string[] = [];

return {
name: 'env-check',
configResolved(config) {
missingVars = REQUIRED_ENV_VARS.filter(key => !config.env[key]);
if (missingVars.length > 0) {
console.warn(
'\n\x1b[33m[env-check] Missing required environment variables:\x1b[0m\n' +
missingVars.map(v => ` \x1b[31m✗ ${v}\x1b[0m`).join('\n') +
'\n\x1b[33m Copy src/.example.env to .env and fill in the values following the guidance described in the example file.\x1b[0m\n'
);
}
},
transformIndexHtml(html) {
if (missingVars.length === 0) return html;

const listItems = missingVars.map(v => `<li><code>${v}</code></li>`).join('');
const overlay = `
<script>
(function() {
var missing = ${JSON.stringify(missingVars)};
if (!missing.length) return;
var overlay = document.createElement('div');
overlay.id = '__env_check_overlay__';
overlay.style.cssText = [
'position:fixed', 'inset:0', 'z-index:99999',
'display:flex', 'align-items:center', 'justify-content:center',
'background:rgba(0,0,0,0.85)', 'font-family:monospace',
].join(';');
overlay.innerHTML = '<div style="background:#1e1e1e;border:2px solid #f87171;border-radius:8px;padding:2rem;max-width:480px;color:#f8f8f8">'
+ '<h2 style="margin:0 0 1rem;color:#f87171;font-size:1.1rem">&#x26A0; Missing environment variables</h2>'
+ '<p style="margin:0 0 1rem;color:#d1d5db;font-size:.875rem">The app cannot start until these are set. Copy <strong>src/.example.env</strong> to <strong>.env</strong> and fill in the values following the guidance described in the example file.</p>'
+ '<ul style="margin:0;padding-left:1.25rem;color:#fca5a5;font-size:.875rem">${listItems}</ul>'
+ '</div>';
document.body.appendChild(overlay);
})();
</script>`;

return html.replace('</body>', overlay + '\n</body>');
},
};
}

export default defineConfig(() => ({
base: './', // This is set to allow for deployments on dynamic subpaths (i.e. - test.phlask.me)
build: {
outDir: 'build',
target: 'es2022'
},
plugins: [
envCheckPlugin(),
react(),
tsconfigPaths(),
]
Expand Down
Loading