diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 089fc8ae..b523d90e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -86,6 +86,7 @@ // "install_deno": "curl -fsSL https://deno.land/install.sh | sh", "install_xdg-utils": "bash ./.devcontainer/scripts/install_xdg-utils.sh", "install_gcloud-cli": "bash ./.devcontainer/scripts/install_gcloud-cli.sh", + "install_firebase-cli": "bash ./.devcontainers/scripts/install_firebase-cli.sh", "configure_pnpm-cli": "bash ./.devcontainer/scripts/install_gcloud-cli.sh", "configure_git-repo": "bash ./.devcontainer/scripts/configure_git-repo.sh" }, diff --git a/.devcontainer/scripts/install_firebase-cli.sh b/.devcontainer/scripts/install_firebase-cli.sh new file mode 100644 index 00000000..c1e935ad --- /dev/null +++ b/.devcontainer/scripts/install_firebase-cli.sh @@ -0,0 +1 @@ +curl -sL https://firebase.tools | bash \ No newline at end of file diff --git a/.env.example b/.env.example index a2b62905..6dfce181 100644 --- a/.env.example +++ b/.env.example @@ -9,4 +9,7 @@ VITE_PROXY_URL=https://localhost:3000 VITE_API_URL=https://localhost:3001 # Advanced -VITE_S3_PREFIX=https://s3.eu-west-3.amazonaws.com/meeting-baas-video \ No newline at end of file +VITE_S3_PREFIX=https://s3.eu-west-3.amazonaws.com/meeting-baas-video + +# Environment +NODE_ENV=development \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3f310b27..d2c2f21c 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ web_modules/ .env.development.local .env.test.local .env.production.local +.env.pre-production.local .env.local # parcel-bundler cache (https://parceljs.org/) diff --git a/apps/api/.env.example b/apps/api/.env.example index 7e2a5b18..13a25f93 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -1,5 +1,5 @@ # MeetingBaas Proxy Config -MEETINGBAAS_API_URL="https://api.meeting-baas.com" +MEETINGBAAS_API_URL="https://api.meetingbaas.com" MEETINGBAAS_S3_URL="https://s3.eu-west-3.amazonaws.com/meeting-baas-video" # Google Auth @@ -14,11 +14,9 @@ TURSO_AUTH_TOKEN="" # Auth BETTER_AUTH_SECRET="" BETTER_AUTH_URL="http://localhost:3001" -BETTER_AUTH_TRUSTED_ORIGINS="http://localhost:5173" -# Keyless Config -# This section is a work-in-progress +# CORS +API_TRUSTED_ORIGINS="http://localhost:5173" -# Hono Firebase Compatability -# https://github.com/honojs/hono/issues/1695 -# NODEJS_HELPERS="0" \ No newline at end of file +# Environment +NODE_ENV=development \ No newline at end of file diff --git a/apps/api/.firebaserc b/apps/api/.firebaserc deleted file mode 100644 index a851630f..00000000 --- a/apps/api/.firebaserc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "projects": { - "transcript-seeker": "transcript-seeker-bdc29" - }, - "targets": { - "transcript-seeker-api-c8419": [ - "transcript-seeker-api-c8419" - ] - }, - "etags": {} -} diff --git a/apps/api/package.json b/apps/api/package.json index 325951f5..f5308701 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -20,7 +20,7 @@ "dependencies": { "@hono/node-server": "^1.13.2", "@libsql/client": "^0.14.0", - "better-auth": "0.7.1-beta.6", + "better-auth": "0.7.3", "dotenv": "^16.4.5", "drizzle-orm": "^0.35.2", "firebase-admin": "^12.6.0", diff --git a/apps/api/src/lib/auth.ts b/apps/api/src/lib/auth.ts index c381d5eb..056fc356 100644 --- a/apps/api/src/lib/auth.ts +++ b/apps/api/src/lib/auth.ts @@ -9,6 +9,7 @@ export const auth = betterAuth({ logger: { verboseLogging: true, }, + trustedOrigins: process.env.API_TRUSTED_ORIGINS?.split(','), socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, diff --git a/apps/api/src/routes/auth.ts b/apps/api/src/routes/auth.ts index 5274c65c..ce69056d 100644 --- a/apps/api/src/routes/auth.ts +++ b/apps/api/src/routes/auth.ts @@ -8,7 +8,7 @@ const authRouter = new Hono(); authRouter.use( '/**', cors({ - origin: process.env.BETTER_AUTH_TRUSTED_ORIGINS!, + origin: process.env.API_TRUSTED_ORIGINS?.split(',') ?? [], allowHeaders: ['Content-Type', 'Authorization'], allowMethods: ['POST', 'GET', 'OPTIONS'], exposeHeaders: ['Content-Length'], diff --git a/apps/api/src/routes/calendars.ts b/apps/api/src/routes/calendars.ts index 91d1d5d2..6c63bda4 100644 --- a/apps/api/src/routes/calendars.ts +++ b/apps/api/src/routes/calendars.ts @@ -10,7 +10,7 @@ const calendars = new Hono(); calendars.use( '/*', cors({ - origin: process.env.BETTER_AUTH_TRUSTED_ORIGINS!, + origin: process.env.API_TRUSTED_ORIGINS?.split(',') ?? [], exposeHeaders: ['Content-Length'], maxAge: 600, credentials: true, diff --git a/apps/docs/.env.example b/apps/docs/.env.example index c7fb1518..1883dc22 100644 --- a/apps/docs/.env.example +++ b/apps/docs/.env.example @@ -1,2 +1,8 @@ ORAMA_PRIVATE_API_KEY="" -ORAMA_INDEX_ID="" \ No newline at end of file +ORAMA_INDEX_ID="" + +NEXT_PUBLIC_ORAMA_API_KEY="" +NEXT_PUBLIC_ORAMA_ENDPOINT="" + +# Environment +NODE_ENV=development \ No newline at end of file diff --git a/apps/docs/content/docs/concepts/environment-variables.mdx b/apps/docs/content/docs/concepts/environment-variables.mdx index 37cd908b..f9e610a7 100644 --- a/apps/docs/content/docs/concepts/environment-variables.mdx +++ b/apps/docs/content/docs/concepts/environment-variables.mdx @@ -184,7 +184,7 @@ Create a `.env.development.local` file in the below directory of your project an These values are used by the api to figure out the api url for baas servers. ```txt title=".env.development.local" -MEETINGBAAS_API_URL="https://api.meeting-baas.com" +MEETINGBAAS_API_URL="https://api.meetingbaas.com" MEETINGBAAS_S3_URL="https://s3.eu-west-3.amazonaws.com/meeting-baas-video" ``` @@ -247,13 +247,14 @@ Create a `.env.development.local` file in the below directory of your project an -### MeetingBaas Proxy Configuration +### MeetingBaas Configuration These values are used by the api to figure out the api url for baas servers. ```txt title=".env.development.local" -MEETINGBAAS_API_URL="https://api.meeting-baas.com" -MEETINGBAAS_S3_URL="https://s3.eu-west-3.amazonaws.com/meeting-baas-video" +NITRO_MEETINGBAAS_API_URL="https://api.meetingbaas.com" +NITRO_MEETINGBAAS_S3_URL="https://s3.eu-west-3.amazonaws.com/meeting-baas-video" +NITRO_TRUSTED_ORIGINS="http://localhost:5173" # comma separated list of trusted origins ``` @@ -285,16 +286,21 @@ TURSO_AUTH_TOKEN="" ### Authentication Configuration + + When deploying to Google Cloud Run with a custom domain, you should set the + `BETTER_AUTH_URL` environment variable to the custom domain. + + These values are used by the api to perform authentication. Please follow the [guide](/docs/concepts/api/authentication) for more details: ```txt title=".env.development.local" BETTER_AUTH_SECRET="" BETTER_AUTH_URL="http://localhost:3001" -BETTER_AUTH_TRUSTED_ORIGINS="http://localhost:5173" +API_TRUSTED_ORIGINS="http://localhost:5173" ``` - The `BETTER_AUTH_TRUSTED_ORIGINS` is not only used for authentication but also + The `API_TRUSTED_ORIGINS` is not only used for authentication but also for CORS configuration. diff --git a/apps/docs/content/docs/guides/deployment/firebase.mdx b/apps/docs/content/docs/guides/deployment/firebase.mdx index 1799577b..80f7f992 100644 --- a/apps/docs/content/docs/guides/deployment/firebase.mdx +++ b/apps/docs/content/docs/guides/deployment/firebase.mdx @@ -30,8 +30,7 @@ For more information on Firebase Hosting, refer to the official [Firebase Hostin If not already, create a Firebase project in the Firebase Console: 1. Create a project named **Transcript Seeker**. -2. Then, create two new web apps: - - `transcript-seeker-api`: Replace `transcript-seeker-api-c8419` in `firebase.json` and `.firebaserc` with this new ID. +2. Then, create a new web app: - `transcript-seeker-proxy`: Replace `transcript-seeker-proxy` in `firebase.json` and `.firebaserc` with this new ID. 3. Navigate to **Hosting** and click "Get Started." 4. Finally, Replace `transcript-seeker-bdc29` in `firebase.json` and `.firebaserc` with your project id. (This is for firebase hosting, when you click on get started it automatically creates a hosting project with ur app id) @@ -197,6 +196,10 @@ The command below builds and deploys the Cloud Run service. Modify the `SERVICE_ can replace `COMMIT_SHA` with a unique identifier. + + If you have already deployed the frontend and are encountering a CORS error, it may be due to the API being built for production. Once the build is complete, the CORS error should be resolved. + + ```bash title="Terminal" export COMMIT_SHA=$(git rev-parse --short HEAD) export DEPLOY_REGION="us-central1" diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 6ee83fdf..afbdff92 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -10,16 +10,16 @@ const withMDX = createMDX(); /** @type {import('next').NextConfig} */ const config = { - output: "export", + // output: "export", reactStrictMode: true, eslint: { // Replaced by root workspace command ignoreDuringBuilds: true, }, - serverExternalPackages: ["ts-morph", "typescript"], - images: { - unoptimized: true, - }, + // serverExternalPackages: ["ts-morph", "typescript"], + // images: { + // unoptimized: true, + // }, }; export default withAnalyzer(withMDX(config)); diff --git a/apps/proxy/.env.example b/apps/proxy/.env.example index 0506a2ff..8127123d 100644 --- a/apps/proxy/.env.example +++ b/apps/proxy/.env.example @@ -1,5 +1,5 @@ # MeetingBaas Proxy Config -NITRO_MEETINGBAAS_API_URL=https://api.meeting-baas.com +NITRO_MEETINGBAAS_API_URL=https://api.meetingbaas.com NITRO_MEETINGBAAS_S3_URL=https://s3.eu-west-3.amazonaws.com/meeting-baas-video # Keyless Config @@ -7,4 +7,10 @@ NITRO_MEETINGBAAS_S3_URL=https://s3.eu-west-3.amazonaws.com/meeting-baas-video # Firebase Deployment Config # Advanced, only use if using firebase deployment -# NITRO_PRESET=firebase \ No newline at end of file +# NITRO_PRESET=firebase + +# Cors +NITRO_TRUSTED_ORIGINS="http://localhost:5173" + +# Environment +NODE_ENV=development \ No newline at end of file diff --git a/apps/proxy/README.md b/apps/proxy/README.md index 95caae70..c0ded31d 100644 --- a/apps/proxy/README.md +++ b/apps/proxy/README.md @@ -10,6 +10,7 @@ Once deployed, make sure to set the following environment variables: - `NITRO_MEETINGBAAS_API_URL` - The URL for the MeetingBaas API - `NITRO_MEETINGBAAS_S3_URL` - The URL for the MeetingBaas S3 bucket +- `NITRO_TRUSTED_ORIGINS` - The trusted cors origins ### Local Development diff --git a/apps/proxy/nitro.config.ts b/apps/proxy/nitro.config.ts index 924fb2c5..8b91051a 100644 --- a/apps/proxy/nitro.config.ts +++ b/apps/proxy/nitro.config.ts @@ -1,20 +1,11 @@ //https://nitro.unjs.io/config -import process from 'node:process'; - -const env = process.env; - -const MEETINGBAAS_API_URL = env.NITRO_MEETINGBAAS_API_URL || 'https://api.meeting-baas.com'; -const MEETINGBAAS_S3_URL = - env.NITRO_MEETINGBAAS_S3_URL || 'https://s3.eu-west-3.amazonaws.com/meeting-baas-video'; - export default defineNitroConfig({ srcDir: 'server', - // https://github.com/unjs/rou3/tree/radix3#route-matcher - routeRules: { - '/api/meetingbaas/**': { proxy: `${MEETINGBAAS_API_URL}/**`, cors: true }, - '/api/s3/**': { proxy: `${MEETINGBAAS_S3_URL}/**`, cors: true }, - // '/proxy/**': { proxy: '/api/**' }, + runtimeConfig: { + trustedOrigins: "https://app.transcriptseeker.com", + meetingbaasApiUrl: "https://api.meetingbaas.com", + meetingbaasS3Url: "https://s3.eu-west-3.amazonaws.com/meeting-baas-video", }, firebase: { diff --git a/apps/proxy/package.json b/apps/proxy/package.json index a966bb20..a1cda44b 100644 --- a/apps/proxy/package.json +++ b/apps/proxy/package.json @@ -30,8 +30,6 @@ }, "prettier": "@meeting-baas/prettier-config", "dependencies": { - "firebase-admin": "^12.6.0", - "firebase-functions": "^6.0.1", - "firebase-functions-test": "^3.3.0" + "h3-proxy": "^1.13.0" } } diff --git a/apps/proxy/server/middleware/cors.ts b/apps/proxy/server/middleware/cors.ts new file mode 100644 index 00000000..47409f80 --- /dev/null +++ b/apps/proxy/server/middleware/cors.ts @@ -0,0 +1,15 @@ +export default defineEventHandler((event) => { + const trustedOrigins = useRuntimeConfig(event).trustedOrigins.split(','); + const didHandleCors = handleCors(event, { + origin: trustedOrigins, + preflight: { + statusCode: 204, + }, + credentials: true, + methods: '*', + }); + + if (didHandleCors) { + return; + } +}); diff --git a/apps/proxy/server/middleware/meetingbaas-proxy.ts b/apps/proxy/server/middleware/meetingbaas-proxy.ts new file mode 100644 index 00000000..cdb0e4b0 --- /dev/null +++ b/apps/proxy/server/middleware/meetingbaas-proxy.ts @@ -0,0 +1,15 @@ +import { createProxyEventHandler } from 'h3-proxy' + +export default eventHandler((event) => { + const { meetingbaasApiUrl } = useRuntimeConfig(event); + + const proxy = createProxyEventHandler({ + target: meetingbaasApiUrl, + pathRewrite: { + '^/api/meetingbaas': '', + }, + pathFilter: ['/api/meetingbaas/**'] + }) + + return proxy(event); +}); diff --git a/apps/proxy/server/middleware/s3-proxy.ts b/apps/proxy/server/middleware/s3-proxy.ts new file mode 100644 index 00000000..e148e4ac --- /dev/null +++ b/apps/proxy/server/middleware/s3-proxy.ts @@ -0,0 +1,15 @@ +import { createProxyEventHandler } from 'h3-proxy' + +export default eventHandler((event) => { + const { meetingbaasS3Url } = useRuntimeConfig(event); + + const proxy = createProxyEventHandler({ + target: meetingbaasS3Url, + pathRewrite: { + '^/api/s3': '', + }, + pathFilter: ['/api/s3/**'] + }) + + return proxy(event); +}); diff --git a/apps/web/package.json b/apps/web/package.json index e3e9ddc1..be007f7c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -29,7 +29,7 @@ "@tanstack/react-table": "^8.19.2", "@vidstack/react": "^1.11.24", "assemblyai": "^4.6.1", - "better-auth": "0.7.1-beta.6", + "better-auth": "0.7.3", "date-fns": "^3.6.0", "dotenv-cli": "catalog:", "hls.js": "^1.5.13", diff --git a/apps/web/src/components/calendars/app-sidebar.tsx b/apps/web/src/components/calendars/app-sidebar.tsx index 9cbf4693..11f49569 100644 --- a/apps/web/src/components/calendars/app-sidebar.tsx +++ b/apps/web/src/components/calendars/app-sidebar.tsx @@ -24,19 +24,24 @@ import { SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, + SidebarRail, } from '@meeting-baas/ui/sidebar'; import ServerAvailablity from '../server-availablity'; import { CreateCalendar } from './create-calendar'; +import UserMenu from './user-menu'; +import { useSession } from '@/lib/auth'; +import { Session, User } from 'better-auth'; interface AppSidebarProps { calendars?: CalendarBaasData[] | null; isLoading: boolean; deleteCalendar: (id: string) => void; + session: { session: Session | null; user: User | null }; mutate: () => Promise; } -export function AppSidebar({ calendars, isLoading, deleteCalendar, mutate }: AppSidebarProps) { +export function AppSidebar({ calendars, isLoading, deleteCalendar, session, mutate }: AppSidebarProps) { return ( @@ -73,13 +78,10 @@ export function AppSidebar({ calendars, isLoading, deleteCalendar, mutate }: App
toggleCalendarVisibility(calendar.uuid)} > - toggleCalendarVisibility(calendar.uuid)} + {/* + /> */} {calendar.name}
@@ -90,17 +92,16 @@ export function AppSidebar({ calendars, isLoading, deleteCalendar, mutate }: App - toggleCalendarVisibility(calendar.uuid)} >
- {/* {visibleCalendarIds.includes(calendar.uuid) ? 'Hide' : 'Show'} Calendar */} + {visibleCalendarIds.includes(calendar.uuid) ? 'Hide' : 'Show'} Calendar -
+ */} deleteCalendar(calendar.uuid)}> Delete Calendar @@ -117,9 +118,9 @@ export function AppSidebar({ calendars, isLoading, deleteCalendar, mutate }: App - - + +
); } diff --git a/apps/web/src/components/calendars/calendar.tsx b/apps/web/src/components/calendars/calendar.tsx index 0963e002..d122eb75 100644 --- a/apps/web/src/components/calendars/calendar.tsx +++ b/apps/web/src/components/calendars/calendar.tsx @@ -32,11 +32,11 @@ import CalendarToolbar from './calendar-toolbar'; import { EventModal } from './event-modal'; interface CalendarProps { - calendarsData: CalendarBaasData[]; - initialEventsData: ExtendedCalendarBaasEvent[]; + calendars: CalendarBaasData[]; + initialEvents: ExtendedCalendarBaasEvent[]; } -function Calendar({ calendarsData, initialEventsData }: CalendarProps) { +function Calendar({ calendars: calendarsData, initialEvents }: CalendarProps) { const [selectedEvent, setSelectedEvent] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isProcessing, setIsProcessing] = useState(false); @@ -44,7 +44,7 @@ function Calendar({ calendarsData, initialEventsData }: CalendarProps) { const { data: eventsData, mutate } = useSWR( ['calendar-events', calendarsData, baasApiKey], - () => initialEventsData, + () => initialEvents, { revalidateOnFocus: false, revalidateOnReconnect: false, diff --git a/apps/web/src/components/calendars/create-calendar.tsx b/apps/web/src/components/calendars/create-calendar.tsx index 1537a48b..7a14e8c8 100644 --- a/apps/web/src/components/calendars/create-calendar.tsx +++ b/apps/web/src/components/calendars/create-calendar.tsx @@ -4,13 +4,14 @@ import { createCalendar } from '@/lib/meetingbaas'; import { toast } from 'sonner'; import type { CreateCalendarParams } from '@meeting-baas/shared'; -import { Button } from '@meeting-baas/ui/button'; +import { Button, ButtonProps } from '@meeting-baas/ui/button'; +import { CalendarPlus } from 'lucide-react'; -interface CreateCalendarProps { +interface CreateCalendarProps extends ButtonProps { mutate: () => Promise; } -export function CreateCalendar({ mutate }: CreateCalendarProps) { +export function CreateCalendar({ mutate, ...props }: CreateCalendarProps) { const [isPending, startTransition] = useTransition(); const { apiKey } = useApiKey({ type: 'meetingbaas' }); @@ -23,6 +24,8 @@ export function CreateCalendar({ mutate }: CreateCalendarProps) { } startTransition(async () => { + const id = toast.loading('Creating calendar...'); + try { const params: CreateCalendarParams = { platform: 'Google', @@ -32,20 +35,23 @@ export function CreateCalendar({ mutate }: CreateCalendarProps) { if (!res) throw new Error('Failed to create calendar.'); toast.success('Success', { description: 'Calendar created successfully. Please refresh the page.', + id }); await mutate(); } catch (error) { console.error('Failed to create calendar:', error); toast.error('Error', { description: 'Failed to create calendar. Please try again.', + id }); } }); }; return ( - + ); } diff --git a/apps/web/src/components/calendars/no-calendars.tsx b/apps/web/src/components/calendars/no-calendars.tsx index 0944bdda..e1444784 100644 --- a/apps/web/src/components/calendars/no-calendars.tsx +++ b/apps/web/src/components/calendars/no-calendars.tsx @@ -1,3 +1,4 @@ +import { buttonVariants } from '@meeting-baas/ui/button'; import { CreateCalendar } from './create-calendar'; interface NoCalendarsProps { @@ -9,7 +10,7 @@ export function NoCalendars({ mutate }: NoCalendarsProps) {

You don't have any calendars yet

Create a calendar to get started

- +
); } diff --git a/apps/web/src/components/calendars/user-menu.tsx b/apps/web/src/components/calendars/user-menu.tsx new file mode 100644 index 00000000..4675bf68 --- /dev/null +++ b/apps/web/src/components/calendars/user-menu.tsx @@ -0,0 +1,116 @@ +'use client'; + +import type { Session, User } from 'better-auth'; +import { signOut } from '@/lib/auth'; +import { BadgeCheck, ChevronsUpDown, LogOut, PlusIcon, UserIcon } from 'lucide-react'; +import { Link } from 'react-router-dom'; + +import { Avatar, AvatarFallback, AvatarImage } from '@meeting-baas/ui/avatar'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@meeting-baas/ui/dropdown-menu'; +import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@meeting-baas/ui/sidebar'; + +import ServerAvailablity from '../server-availablity'; +import SignOut from '../sign-out'; +import { CreateCalendar } from './create-calendar'; + +function UserMenu({ + session, + mutate, +}: { + session: { session: Session | null; user: User | null } | null; + mutate: () => Promise; +}) { + if (!session || !session.user) { + return null; + } + + return ( + + + + + + + {session.user.image && ( + + )} + CN + +
+ {session.user.name} + {session.user.email} +
+ +
+
+ + +
+ + {session.user.image && ( + + )} + CN + +
+ {session.user.name} + {session.user.email} +
+
+
+ + + + + + + + + Account + + + + + + + + + + + + + + + +
+
+
+
+ ); +} + +export default UserMenu; diff --git a/apps/web/src/components/settings/settings-form.tsx b/apps/web/src/components/settings/settings-form.tsx index 90e1e5ca..5f141c09 100644 --- a/apps/web/src/components/settings/settings-form.tsx +++ b/apps/web/src/components/settings/settings-form.tsx @@ -10,6 +10,7 @@ import { Link } from 'react-router-dom'; import { toast } from 'sonner'; import { mutate } from 'swr'; import { z } from 'zod'; +import type { Session } from 'better-auth'; import { cn } from '@meeting-baas/ui'; import { @@ -95,8 +96,9 @@ const ApiKeyField: React.FC = ({ }; export function SettingsForm() { - const { data: session, isPending: isSessionLoading } = useSession(); + const { data: session, isPending: isSessionLoading, error } = useSession(); + const { apiKey: baasApiKey } = useApiKey({ type: 'meetingbaas' }); const { apiKey: openAIApiKey } = useApiKey({ type: 'openai' }); const { apiKey: gladiaApiKey } = useApiKey({ type: 'gladia' }); @@ -251,16 +253,16 @@ export function SettingsForm() { - {session.user + {session?.user ? JSON.stringify(session.user) : isSessionLoading ? 'loading...' : 'not authenticated'} - {session.user && } + {session?.user && } - {!session.user && ( + {!session?.user && ( Login diff --git a/apps/web/src/components/sign-out.tsx b/apps/web/src/components/sign-out.tsx index a6915a60..b64e4d18 100644 --- a/apps/web/src/components/sign-out.tsx +++ b/apps/web/src/components/sign-out.tsx @@ -1,14 +1,17 @@ -import { useTransition } from 'react'; +import React, { useTransition } from 'react'; import { signOut } from '@/lib/auth'; -import { LoaderIcon } from 'lucide-react'; +import { LoaderIcon, LogOut } from 'lucide-react'; -import { Button } from '@meeting-baas/ui/button'; +import { ButtonProps } from '@meeting-baas/ui/button'; -function SignOut() { +interface SignOutProps extends ButtonProps { +} + +function SignOut({ children, ...props }: SignOutProps) { const [isPending, startTransition] = useTransition(); return ( - + ); } diff --git a/apps/web/src/lib/meetingbaas.ts b/apps/web/src/lib/meetingbaas.ts index c1bb13a4..45f84060 100644 --- a/apps/web/src/lib/meetingbaas.ts +++ b/apps/web/src/lib/meetingbaas.ts @@ -42,9 +42,9 @@ export const fetchBotDetails = async ({ ...params }: FetchBotDetailsProps) => { ...params, }); - const data: MeetingData = response.data; + const data: MeetingData | undefined | null = response.data; - if (!data.bot_data.bot?.id) return null; + if (!data?.bot_data.bot?.id) return null; const bot = data.bot_data.bot; const transcripts = data.bot_data.transcripts; diff --git a/apps/web/src/routes/calendars.tsx b/apps/web/src/routes/calendars.tsx index 243ee6ca..4b645d35 100644 --- a/apps/web/src/routes/calendars.tsx +++ b/apps/web/src/routes/calendars.tsx @@ -116,6 +116,7 @@ export default function CalendarsPage() { { @@ -147,7 +148,7 @@ export default function CalendarsPage() { {isCalendarsLoading || isEventsLoading ? ( ) : Array.isArray(calendars) && calendars.length > 0 && events ? ( - + ) : ( { diff --git a/apps/web/src/routes/login.tsx b/apps/web/src/routes/login.tsx index 35c5afbf..69ba0a81 100644 --- a/apps/web/src/routes/login.tsx +++ b/apps/web/src/routes/login.tsx @@ -9,7 +9,7 @@ function LoginPage() { const [isPending, startTransition] = useTransition(); return ( -
+

Login

@@ -22,6 +22,7 @@ function LoginPage() { startTransition(async () => { await signIn.social({ provider: 'google', + // todo: remove this when better auth resolves the callback url automatically callbackURL: '/meetings', }); }); diff --git a/apps/web/tailwind.config.ts b/apps/web/tailwind.config.ts index 72050ef6..81e6320c 100644 --- a/apps/web/tailwind.config.ts +++ b/apps/web/tailwind.config.ts @@ -8,7 +8,7 @@ export default { // We need to append the path to the UI package to the content array so that // those classes are included correctly. content: [...baseConfig.content, '../../packages/ui/src/*.{ts,tsx}'], - presets: [baseConfig], + presets: [baseConfig] // theme: { // extend: { // fontFamily: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74f37817..281639d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,8 +76,8 @@ importers: specifier: ^0.14.0 version: 0.14.0 better-auth: - specifier: 0.7.1-beta.6 - version: 0.7.1-beta.6(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)) + specifier: 0.7.3 + version: 0.7.3(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -281,15 +281,9 @@ importers: apps/proxy: dependencies: - firebase-admin: - specifier: ^12.6.0 - version: 12.7.0 - firebase-functions: - specifier: ^6.0.1 - version: 6.1.0(firebase-admin@12.7.0) - firebase-functions-test: - specifier: ^3.3.0 - version: 3.3.0(firebase-admin@12.7.0)(firebase-functions@6.1.0(firebase-admin@12.7.0))(jest@29.7.0(@types/node@22.9.0)) + h3-proxy: + specifier: ^1.13.0 + version: 1.13.0(h3@1.13.0) devDependencies: '@meeting-baas/eslint-config': specifier: workspace:* @@ -373,8 +367,8 @@ importers: specifier: ^4.6.1 version: 4.7.1 better-auth: - specifier: 0.7.1-beta.6 - version: 0.7.1-beta.6(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)) + specifier: 0.7.3 + version: 0.7.3(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)) date-fns: specifier: ^3.6.0 version: 3.6.0 @@ -4750,11 +4744,11 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - better-auth@0.7.1-beta.6: - resolution: {integrity: sha512-rRDtdxWEtVfcPRBaq88EFhJhjWpoVgO9EGECPUaJO619UmSf+cNO9Ush1X5h6mv82rI8E41sKZnx68TgAfIstQ==} + better-auth@0.7.3: + resolution: {integrity: sha512-ycbYGsxyyWbkEQKxyv/Id15aMcQWwxeBMo7cSBGP0J2wJE48+xh5OTjs7pGEweeYTdnHWkOO3DnVltcWGwvr1w==} - better-call@0.2.14-beta.2: - resolution: {integrity: sha512-j3hFMkD7xZNBXT1lFxrNFbz2Q5wwrzJ+3h+yDWJTVGrbkw7iL0gTA6ZY4hl1Nv3LCgW65wNnGJno9E8vy35oVA==} + better-call@0.2.14-beta.3: + resolution: {integrity: sha512-lA54ETanzM0xUZnQt6lm3BdTr4gVDyAe1DNpCQSTYUnwnGGOmQG8ob0FYivVd0XHsHQK68r01GB5c6cUuu4llQ==} bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} @@ -6150,6 +6144,12 @@ packages: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + h3-proxy@1.13.0: + resolution: {integrity: sha512-STi6jEroxRE9V6j1U6lHsygiTnEx11aFyA6r/TXzQ8/umEB5ckW+kOS+Oue6QXnPOoR2RGJTSmsA+q+S0y60kA==} + engines: {node: '>=18.x'} + peerDependencies: + h3: ^1.6.0 + h3@1.13.0: resolution: {integrity: sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==} @@ -13446,7 +13446,7 @@ snapshots: base64-js@1.5.1: {} - better-auth@0.7.1-beta.6(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)): + better-auth@0.7.3(react@19.0.0-rc-4d577fd2-20241104)(solid-js@1.9.3)(vue@3.5.12(typescript@5.6.3)): dependencies: '@better-fetch/fetch': 1.1.12 '@nanostores/query': 0.3.4(nanostores@0.11.3) @@ -13457,7 +13457,7 @@ snapshots: '@noble/hashes': 1.5.0 '@simplewebauthn/browser': 10.0.0 '@simplewebauthn/server': 10.0.1 - better-call: 0.2.14-beta.2 + better-call: 0.2.14-beta.3 consola: 3.2.3 defu: 6.1.4 jose: 5.9.6 @@ -13475,7 +13475,7 @@ snapshots: - solid-js - vue - better-call@0.2.14-beta.2: + better-call@0.2.14-beta.3: dependencies: '@better-fetch/fetch': 1.1.12 rou3: 0.5.1 @@ -15181,6 +15181,13 @@ snapshots: dependencies: duplexer: 0.1.2 + h3-proxy@1.13.0(h3@1.13.0): + dependencies: + consola: 3.2.3 + h3: 1.13.0 + is-glob: 4.0.3 + micromatch: 4.0.8 + h3@1.13.0: dependencies: cookie-es: 1.2.2 diff --git a/scripts/one-click-deploy.sh b/scripts/one-click-deploy.sh index 3a80cb0d..58b3c1b8 100644 --- a/scripts/one-click-deploy.sh +++ b/scripts/one-click-deploy.sh @@ -16,21 +16,21 @@ echo "Environment set to production." # Build and deploy apps/web echo "Building and deploying apps/web..." cd apps/web -pnpm build +NODE_ENV=production pnpm build firebase deploy || { echo "Firebase deploy for apps/web failed"; exit 1; } cd ../.. # Build and deploy apps/proxy echo "Building and deploying apps/proxy..." cd apps/proxy -pnpm build +NODE_ENV=production pnpm build firebase deploy || { echo "Firebase deploy for apps/proxy failed"; exit 1; } cd ../.. # Build apps/api echo "Building apps/api..." cd apps/api -pnpm build || { echo "Build failed for apps/api"; exit 1; } +NODE_ENV=production pnpm build || { echo "Build failed for apps/api"; exit 1; } cd ../.. # Log Cloud Run deployment @@ -40,7 +40,7 @@ echo "Preparing for Cloud Run deployment..." export COMMIT_SHA=$(git rev-parse --short HEAD) export DEPLOY_REGION="us-central1" export SERVICE_NAME="transcript-seeker-api-prod" -export GITHUB_USERNAME="Meeting-Baas" +export GITHUB_USERNAME="techwithanirudh" echo "Environment variables set:" echo " COMMIT_SHA: $COMMIT_SHA" diff --git a/turbo.json b/turbo.json index b8cbf697..db50f2a0 100644 --- a/turbo.json +++ b/turbo.json @@ -67,8 +67,11 @@ "TURSO_AUTH_TOKEN", "BETTER_AUTH_SECRET", "BETTER_AUTH_URL", - "BETTER_AUTH_TRUSTED_ORIGINS", - "ORAMA_PRIVATE_API_KEY" + "API_TRUSTED_ORIGINS", + "ORAMA_PRIVATE_API_KEY", + "ORAMA_INDEX_ID", + "NEXT_PUBLIC_ORAMA_API_KEY", + "NEXT_PUBLIC_ORAMA_ENDPOINT" ], "globalPassThroughEnv": [ "NODE_ENV",