diff --git a/packages/bolt/README.md b/packages/bolt/README.md index 3f30735..c4cedb0 100644 --- a/packages/bolt/README.md +++ b/packages/bolt/README.md @@ -37,10 +37,10 @@ VITE_LOG_LEVEL=debug ``` If you want to run authentication against a local StackBlitz instance, add: + ``` VITE_CLIENT_ORIGIN=https://local.stackblitz.com:3000 ``` -` **Important**: Never commit your `.env.local` file to version control. It's already included in .gitignore. diff --git a/packages/bolt/app/components/chat/Chat.client.tsx b/packages/bolt/app/components/chat/Chat.client.tsx index e5400f9..2e89dbf 100644 --- a/packages/bolt/app/components/chat/Chat.client.tsx +++ b/packages/bolt/app/components/chat/Chat.client.tsx @@ -47,7 +47,7 @@ export function ChatImpl({ initialMessages, storeMessageHistory }: ChatProps) { const { messages, isLoading, input, handleInputChange, setInput, handleSubmit, stop, append } = useChat({ api: '/api/chat', onError: (error) => { - logger.error(error); + logger.error('Request failed\n\n', error); toast.error('There was an error processing your request'); }, onFinish: () => { diff --git a/packages/bolt/app/components/header/Header.tsx b/packages/bolt/app/components/header/Header.tsx index 5fd661c..c5da1f6 100644 --- a/packages/bolt/app/components/header/Header.tsx +++ b/packages/bolt/app/components/header/Header.tsx @@ -1,6 +1,6 @@ import { ClientOnly } from 'remix-utils/client-only'; -import { OpenStackBlitz } from './OpenStackBlitz.client'; import { IconButton } from '~/components/ui/IconButton'; +import { OpenStackBlitz } from './OpenStackBlitz.client'; export function Header() { return ( diff --git a/packages/bolt/app/lib/.server/login.ts b/packages/bolt/app/lib/.server/login.ts index 2ce10fd..5c84c5c 100644 --- a/packages/bolt/app/lib/.server/login.ts +++ b/packages/bolt/app/lib/.server/login.ts @@ -1,12 +1,5 @@ -import { env } from 'node:process'; -import { isAuthenticated } from './sessions'; import { json, redirect, type LoaderFunctionArgs } from '@remix-run/cloudflare'; - -export function verifyPassword(password: string, cloudflareEnv: Env) { - const loginPassword = env.LOGIN_PASSWORD || cloudflareEnv.LOGIN_PASSWORD; - - return password === loginPassword; -} +import { isAuthenticated } from './sessions'; type RequestArgs = Pick; @@ -14,7 +7,7 @@ export async function handleAuthRequest(args: T, body: ob const { request, context } = args; const { authenticated, response } = await isAuthenticated(request, context.cloudflare.env); - if (authenticated) { + if (authenticated || import.meta.env.VITE_DISABLE_AUTH) { return json(body, response); } @@ -25,7 +18,7 @@ export async function handleWithAuth(args: T, handler: (a const { request, context } = args; const { authenticated, response } = await isAuthenticated(request, context.cloudflare.env); - if (authenticated) { + if (authenticated || import.meta.env.VITE_DISABLE_AUTH) { const handlerResponse = await handler(args); if (response) { diff --git a/packages/bolt/app/lib/.server/sessions.ts b/packages/bolt/app/lib/.server/sessions.ts index 96bc17d..9a66eb6 100644 --- a/packages/bolt/app/lib/.server/sessions.ts +++ b/packages/bolt/app/lib/.server/sessions.ts @@ -1,7 +1,7 @@ import { createCookieSessionStorage, redirect } from '@remix-run/cloudflare'; import { decodeJwt } from 'jose'; -import { request as doRequest } from '~/lib/fetch'; import { CLIENT_ID, CLIENT_ORIGIN } from '~/lib/constants'; +import { request as doRequest } from '~/lib/fetch'; import { logger } from '~/utils/logger'; const DEV_SESSION_SECRET = import.meta.env.DEV ? 'LZQMrERo3Ewn/AbpSYJ9aw==' : undefined; @@ -33,7 +33,7 @@ export async function isAuthenticated(request: Request, env: Env) { try { data = await refreshToken(token); } catch { - // ignore + // we can ignore the error here because it's handled below } if (data != null) { diff --git a/packages/bolt/app/routes/login.tsx b/packages/bolt/app/routes/login.tsx index 421f9e4..b609027 100644 --- a/packages/bolt/app/routes/login.tsx +++ b/packages/bolt/app/routes/login.tsx @@ -1,16 +1,16 @@ import { json, redirect, + redirectDocument, type ActionFunctionArgs, type LoaderFunctionArgs, - redirectDocument, } from '@remix-run/cloudflare'; import { useFetcher, useLoaderData } from '@remix-run/react'; import { auth, type AuthAPI } from '@webcontainer/api'; import { useEffect, useState } from 'react'; import { createUserSession, isAuthenticated, validateAccessToken } from '~/lib/.server/sessions'; -import { request as doRequest } from '~/lib/fetch'; import { CLIENT_ID, CLIENT_ORIGIN } from '~/lib/constants'; +import { request as doRequest } from '~/lib/fetch'; import { logger } from '~/utils/logger'; export async function loader({ request, context }: LoaderFunctionArgs) { @@ -49,7 +49,7 @@ export async function action({ request, context }: ActionFunctionArgs) { throw await response.json(); } } catch (error) { - logger.warn('Authentication failure'); + logger.warn('Authentication failed'); logger.warn(error); return json({ error: 'invalid-token' as const }, { status: 401 }); @@ -100,7 +100,6 @@ export default function Login() {

Login

- {redirected ? 'Processing auth...' : } @@ -162,7 +161,6 @@ function LoginForm() { > {login?.kind === 'pending' ? 'Authenticating...' : 'Continue with StackBlitz'} - {login?.kind === 'error' && (