From d99ab22b56f5409b325a419a3dd9e5c954b078db Mon Sep 17 00:00:00 2001 From: Frank Noirot Date: Tue, 30 Apr 2024 19:13:46 -0400 Subject: [PATCH] Allow developers to override token behavior only for LSP plugin (#2223) --- .env.development | 1 + README.md | 6 +++++- src/components/LspProvider.tsx | 2 +- src/env.ts | 3 +++ src/machines/authMachine.ts | 28 +++++++++++++++++----------- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.env.development b/.env.development index a82a63f2d..5881d7388 100644 --- a/.env.development +++ b/.env.development @@ -3,3 +3,4 @@ VITE_KC_API_BASE_URL=https://api.dev.zoo.dev VITE_KC_SITE_BASE_URL=https://dev.zoo.dev VITE_KC_SKIP_AUTH=false VITE_KC_CONNECTION_TIMEOUT_MS=5000 +VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local" diff --git a/README.md b/README.md index f97c6ae00..1fb96dfa6 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,11 @@ finally, to run the web app only, run: yarn start ``` -## Developing in Chrome +### Development environment variables + +The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service. + +### Developing in Chrome Chrome is in the process of rolling out a new default which [blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/). diff --git a/src/components/LspProvider.tsx b/src/components/LspProvider.tsx index 7007152be..272b03bc5 100644 --- a/src/components/LspProvider.tsx +++ b/src/components/LspProvider.tsx @@ -85,7 +85,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => { }, }, } = useSettingsAuthContext() - const token = auth?.context?.token + const token = auth?.context.token const navigate = useNavigate() const { overallState } = useNetworkStatus() const isNetworkOkay = overallState === NetworkHealthState.Ok diff --git a/src/env.ts b/src/env.ts index 57b64e114..f1c167944 100644 --- a/src/env.ts +++ b/src/env.ts @@ -7,5 +7,8 @@ export const VITE_KC_API_BASE_URL = import.meta.env.VITE_KC_API_BASE_URL export const VITE_KC_SITE_BASE_URL = import.meta.env.VITE_KC_SITE_BASE_URL export const VITE_KC_CONNECTION_TIMEOUT_MS = import.meta.env .VITE_KC_CONNECTION_TIMEOUT_MS +export const VITE_KC_DEV_TOKEN = import.meta.env.VITE_KC_DEV_TOKEN as + | string + | undefined export const TEST = import.meta.env.TEST export const DEV = import.meta.env.DEV diff --git a/src/machines/authMachine.ts b/src/machines/authMachine.ts index 0fd13cb3f..d08c039e2 100644 --- a/src/machines/authMachine.ts +++ b/src/machines/authMachine.ts @@ -2,7 +2,7 @@ import { createMachine, assign } from 'xstate' import { Models } from '@kittycad/lib' import withBaseURL from '../lib/withBaseURL' import { isTauri } from 'lib/isTauri' -import { VITE_KC_API_BASE_URL } from 'env' +import { VITE_KC_API_BASE_URL, VITE_KC_DEV_TOKEN } from 'env' import { getUser as getUserTauri } from 'lib/tauri' const SKIP_AUTH = @@ -112,14 +112,25 @@ export const authMachine = createMachine( ) async function getUser(context: UserContext) { + const token = + context.token && context.token !== '' + ? context.token + : getCookie(COOKIE_NAME) || + localStorage?.getItem(TOKEN_PERSIST_KEY) || + VITE_KC_DEV_TOKEN const url = withBaseURL('/user') const headers: { [key: string]: string } = { 'Content-Type': 'application/json', } - if (!context.token && isTauri()) throw new Error('No token found') - if (context.token) headers['Authorization'] = `Bearer ${context.token}` - if (SKIP_AUTH) return LOCAL_USER + if (!token && isTauri()) throw new Error('No token found') + if (token) headers['Authorization'] = `Bearer ${context.token}` + + if (SKIP_AUTH) + return { + user: LOCAL_USER, + token, + } const userPromise = !isTauri() ? fetch(url, { @@ -136,13 +147,8 @@ async function getUser(context: UserContext) { if ('error_code' in user) throw new Error(user.message) return { - user, - token: - context.token && context.token !== '' - ? context.token - : getCookie(COOKIE_NAME) || - localStorage?.getItem(TOKEN_PERSIST_KEY) || - '', + user: user as Models['User_type'], + token, } }