fixes to login/logout and hide Random Answer button
This commit is contained in:
parent
8c52e29e34
commit
5da3de3152
@ -1 +1 @@
|
|||||||
2aa2de355546f6401f80a07e00066bd83f37fdc6-803b2c2ecad09a0fbca070296808a53489de891a-e9eccd451b778829eb2f2c9752c670b707e1268b
|
e43b26fea335b87cb7d2747d85540177b96c7847-803b2c2ecad09a0fbca070296808a53489de891a-e9eccd451b778829eb2f2c9752c670b707e1268b
|
||||||
|
@ -39,6 +39,7 @@ export FROM_SECRETS_MANAGER=true
|
|||||||
|
|
||||||
# React needs the prefixed var at BUILD time
|
# React needs the prefixed var at BUILD time
|
||||||
export REACT_APP_GOOGLE_MAPS_API_KEY="$GOOGLE_MAPS_API_KEY"
|
export REACT_APP_GOOGLE_MAPS_API_KEY="$GOOGLE_MAPS_API_KEY"
|
||||||
|
export REACT_APP_ENV_NAME="$ENV_NAME"
|
||||||
|
|
||||||
|
|
||||||
# ───────────────────────── node + npm ci cache ─────────────────────────
|
# ───────────────────────── node + npm ci cache ─────────────────────────
|
||||||
|
61
rotate_dev_secrets.sh
Executable file
61
rotate_dev_secrets.sh
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT=aptivaai-dev
|
||||||
|
ENV=dev
|
||||||
|
|
||||||
|
add_ver() {
|
||||||
|
local name="$1" ; shift
|
||||||
|
gcloud secrets versions add "${name}_${ENV}" --data-file=- --project="$PROJECT" >/dev/null
|
||||||
|
echo "✅ ${name}_${ENV} rotated"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "🔐 Rotating DEV secrets in ${PROJECT}"
|
||||||
|
|
||||||
|
# ── Generate fresh randoms
|
||||||
|
openssl rand -hex 32 | add_ver JWT_SECRET
|
||||||
|
|
||||||
|
# ── Paste new third-party keys (press Enter to skip any you don't want to rotate)
|
||||||
|
read -s -p "OPENAI_API_KEY_${ENV}: " OPENAI && echo
|
||||||
|
[[ -n "${OPENAI}" ]] && printf "%s" "$OPENAI" | add_ver OPENAI_API_KEY
|
||||||
|
|
||||||
|
read -p "ONET_USERNAME_${ENV}: " ONETU && echo
|
||||||
|
[[ -n "${ONETU}" ]] && printf "%s" "$ONETU" | add_ver ONET_USERNAME
|
||||||
|
|
||||||
|
read -s -p "ONET_PASSWORD_${ENV}: " ONETP && echo
|
||||||
|
[[ -n "${ONETP}" ]] && printf "%s" "$ONETP" | add_ver ONET_PASSWORD
|
||||||
|
|
||||||
|
read -s -p "STRIPE_SECRET_KEY_${ENV}: " SSK && echo
|
||||||
|
[[ -n "${SSK}" ]] && printf "%s" "$SSK" | add_ver STRIPE_SECRET_KEY
|
||||||
|
|
||||||
|
read -p "STRIPE_PUBLISHABLE_KEY_${ENV}: " SPK && echo
|
||||||
|
[[ -n "${SPK}" ]] && printf "%s" "$SPK" | add_ver STRIPE_PUBLISHABLE_KEY
|
||||||
|
|
||||||
|
read -s -p "STRIPE_WH_SECRET_${ENV}: " SWH && echo
|
||||||
|
[[ -n "${SWH}" ]] && printf "%s" "$SWH" | add_ver STRIPE_WH_SECRET
|
||||||
|
|
||||||
|
read -s -p "SUPPORT_SENDGRID_API_KEY_${ENV}: " SG && echo
|
||||||
|
[[ -n "${SG}" ]] && printf "%s" "$SG" | add_ver SUPPORT_SENDGRID_API_KEY
|
||||||
|
|
||||||
|
read -s -p "EMAIL_INDEX_SECRET_${ENV}: " EIDX && echo
|
||||||
|
[[ -n "${EIDX}" ]] && printf "%s" "$EIDX" | add_ver EMAIL_INDEX_SECRET
|
||||||
|
|
||||||
|
read -p "TWILIO_ACCOUNT_SID_${ENV}: " TSID && echo
|
||||||
|
[[ -n "${TSID}" ]] && printf "%s" "$TSID" | add_ver TWILIO_ACCOUNT_SID
|
||||||
|
|
||||||
|
read -s -p "TWILIO_AUTH_TOKEN_${ENV}: " TAUT && echo
|
||||||
|
[[ -n "${TAUT}" ]] && printf "%s" "$TAUT" | add_ver TWILIO_AUTH_TOKEN
|
||||||
|
|
||||||
|
read -p "TWILIO_MESSAGING_SERVICE_SID_${ENV}: " TMSS && echo
|
||||||
|
[[ -n "${TMSS}" ]] && printf "%s" "$TMSS" | add_ver TWILIO_MESSAGING_SERVICE_SID
|
||||||
|
|
||||||
|
# Optional: rotate Maps if it was in the leaked image
|
||||||
|
read -s -p "GOOGLE_MAPS_API_KEY_${ENV} (optional): " GMAPS && echo
|
||||||
|
[[ -n "${GMAPS}" ]] && printf "%s" "$GMAPS" | add_ver GOOGLE_MAPS_API_KEY
|
||||||
|
|
||||||
|
echo "🔁 Rebuilding DEV with fresh secrets…"
|
||||||
|
ENV=dev ./deploy_all.sh
|
||||||
|
|
||||||
|
echo "🧪 Verifying runtime env inside containers:"
|
||||||
|
docker compose exec -T server1 sh -lc 'printenv | egrep "JWT_SECRET|OPENAI|ONET|STRIPE_(SECRET|PUBLISH|WH)|SENDGRID|EMAIL_INDEX|TWILIO|TOKEN_MAX_AGE_MS|ACCESS_COOKIE_NAME|COOKIE_(SECURE|SAMESITE)"'
|
||||||
|
echo "✅ Done."
|
29
src/App.js
29
src/App.js
@ -69,6 +69,7 @@ function App() {
|
|||||||
const [retireProps, setRetireProps] = useState(null);
|
const [retireProps, setRetireProps] = useState(null);
|
||||||
const [supportOpen, setSupportOpen] = useState(false);
|
const [supportOpen, setSupportOpen] = useState(false);
|
||||||
const [userEmail, setUserEmail] = useState('');
|
const [userEmail, setUserEmail] = useState('');
|
||||||
|
const [loggingOut, setLoggingOut] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const AUTH_HOME = '/signin-landing';
|
const AUTH_HOME = '/signin-landing';
|
||||||
@ -167,9 +168,15 @@ const showPremiumCTA = !premiumPaths.some(p =>
|
|||||||
// ==============================
|
// ==============================
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
if (loggingOut) return;
|
||||||
|
|
||||||
// Don’t do auth probe on reset-password
|
// Skip auth probe on all public auth routes
|
||||||
if (location.pathname.startsWith('/reset-password')) {
|
if (
|
||||||
|
location.pathname.startsWith('/reset-password') ||
|
||||||
|
location.pathname === '/signin' ||
|
||||||
|
location.pathname === '/signup' ||
|
||||||
|
location.pathname === '/forgot-password'
|
||||||
|
) {
|
||||||
try { localStorage.removeItem('id'); } catch {}
|
try { localStorage.removeItem('id'); } catch {}
|
||||||
setIsAuthenticated(false);
|
setIsAuthenticated(false);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
@ -177,6 +184,7 @@ useEffect(() => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
@ -208,7 +216,7 @@ useEffect(() => {
|
|||||||
|
|
||||||
// include isAuthScreen if you prefer, but this local check avoids a dep loop
|
// include isAuthScreen if you prefer, but this local check avoids a dep loop
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [location.pathname, navigate]);
|
}, [location.pathname, navigate, loggingOut]);
|
||||||
|
|
||||||
/* =====================
|
/* =====================
|
||||||
Support Modal Email
|
Support Modal Email
|
||||||
@ -234,6 +242,7 @@ useEffect(() => {
|
|||||||
|
|
||||||
|
|
||||||
const confirmLogout = async () => {
|
const confirmLogout = async () => {
|
||||||
|
setLoggingOut(true);
|
||||||
// 1) Ask the server to clear the session cookie
|
// 1) Ask the server to clear the session cookie
|
||||||
try {
|
try {
|
||||||
// If you created /logout (no /api prefix):
|
// If you created /logout (no /api prefix):
|
||||||
@ -268,6 +277,7 @@ const confirmLogout = async () => {
|
|||||||
|
|
||||||
// 4) Back to sign-in
|
// 4) Back to sign-in
|
||||||
navigate('/signin', { replace: true });
|
navigate('/signin', { replace: true });
|
||||||
|
setLoggingOut(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelLogout = () => {
|
const cancelLogout = () => {
|
||||||
@ -298,8 +308,12 @@ const cancelLogout = () => {
|
|||||||
user, setUser}}
|
user, setUser}}
|
||||||
>
|
>
|
||||||
<ChatCtx.Provider value={{ setChatSnapshot,
|
<ChatCtx.Provider value={{ setChatSnapshot,
|
||||||
openSupport: () => { setDrawerPane('support'); setDrawerOpen(true); },
|
openSupport: () => {
|
||||||
|
if (!isAuthenticated) return;
|
||||||
|
setDrawerPane('support'); setDrawerOpen(true);
|
||||||
|
},
|
||||||
openRetire : (props) => {
|
openRetire : (props) => {
|
||||||
|
if (!isAuthenticated || !canShowRetireBot) return;
|
||||||
if (!canShowRetireBot) {
|
if (!canShowRetireBot) {
|
||||||
console.warn('Retirement bot disabled on this page');
|
console.warn('Retirement bot disabled on this page');
|
||||||
return;
|
return;
|
||||||
@ -549,10 +563,11 @@ const cancelLogout = () => {
|
|||||||
|
|
||||||
{/* LOGOUT BUTTON */}
|
{/* LOGOUT BUTTON */}
|
||||||
<button
|
<button
|
||||||
className="text-red-600 hover:text-red-800 bg-transparent border-none"
|
|
||||||
onClick={handleLogoutClick}
|
onClick={handleLogoutClick}
|
||||||
|
disabled={loggingOut}
|
||||||
|
className="text-red-600 hover:text-red-800 bg-transparent border-none disabled:opacity-60"
|
||||||
>
|
>
|
||||||
Logout
|
{loggingOut ? 'Signing out…' : 'Logout'}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* SHOW WARNING MODAL IF needed */}
|
{/* SHOW WARNING MODAL IF needed */}
|
||||||
@ -699,6 +714,7 @@ const cancelLogout = () => {
|
|||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{isAuthenticated && (
|
||||||
<ChatDrawer
|
<ChatDrawer
|
||||||
open={drawerOpen}
|
open={drawerOpen}
|
||||||
onOpenChange={setDrawerOpen}
|
onOpenChange={setDrawerOpen}
|
||||||
@ -713,6 +729,7 @@ const cancelLogout = () => {
|
|||||||
uiToolHandlers={uiToolHandlers}
|
uiToolHandlers={uiToolHandlers}
|
||||||
canShowRetireBot={canShowRetireBot}
|
canShowRetireBot={canShowRetireBot}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Session Handler (Optional) */}
|
{/* Session Handler (Optional) */}
|
||||||
<SessionExpiredHandler />
|
<SessionExpiredHandler />
|
||||||
|
@ -23,6 +23,7 @@ const InterestInventory = () => {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [userProfile, setUserProfile] = useState(null);
|
const [userProfile, setUserProfile] = useState(null);
|
||||||
|
const isProd = (process.env.REACT_APP_ENV_NAME || '').toLowerCase() === 'prod';
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -290,6 +291,7 @@ const InterestInventory = () => {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{!isProd && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={randomizeAnswers}
|
onClick={randomizeAnswers}
|
||||||
@ -298,6 +300,7 @@ const InterestInventory = () => {
|
|||||||
>
|
>
|
||||||
Randomize Answers
|
Randomize Answers
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user