mirror of
				https://github.com/bartvdbraak/omnidash.git
				synced 2025-10-30 16:09:11 +00:00 
			
		
		
		
	Merge pull request #212 from bartvdbraak/unlighthouse-auth
Add Dockerfile for backend service and unlighthouse authentication
This commit is contained in:
		
						commit
						3015ae0486
					
				
					 16 changed files with 3087 additions and 166 deletions
				
			
		
							
								
								
									
										10
									
								
								.github/workflows/unlighthouse.yaml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/unlighthouse.yaml
									
										
									
									
										vendored
									
									
								
							|  | @ -74,14 +74,14 @@ jobs: | ||||||
|           timeout: 360 |           timeout: 360 | ||||||
| 
 | 
 | ||||||
|       - name: Install Dependencies |       - name: Install Dependencies | ||||||
|         run: pnpm install -g @unlighthouse/cli puppeteer |         run: pnpm install | ||||||
| 
 | 
 | ||||||
|       - name: Run Unlighthouse |       - name: Run Unlighthouse | ||||||
|         run: | |         run: | | ||||||
|           unlighthouse-ci \ |           export SCAN_URL="${{ github.ref == 'refs/heads/main' && env.WEBSITE_URL || steps.vercel_preview_url.outputs.preview_url }}" | ||||||
|             --site "${{ github.ref == 'refs/heads/main' && env.WEBSITE_URL || steps.vercel_preview_url.outputs.preview_url }}" \ |           export AUTH_COOKIE="$(curl "https://$SCAN_URL/auth?/login" -H "Origin: https://$SCAN_URL" -F "email=test_user" -F "password=${{ secrets.TEST_USER_PASSWORD }}" --verbose 2>&1 | awk -F'pb_auth=' '/pb_auth/{print $2;exit}' | awk -F';' '{print $1}')" | ||||||
|             --reporter jsonExpanded \ | 
 | ||||||
|             --build-static |           pnpm run unlighthouse | ||||||
| 
 | 
 | ||||||
|       - name: Upload report to Cloudflare pages |       - name: Upload report to Cloudflare pages | ||||||
|         uses: cloudflare/wrangler-action@v3.4.1 |         uses: cloudflare/wrangler-action@v3.4.1 | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -8,3 +8,4 @@ node_modules | ||||||
| !.env.example | !.env.example | ||||||
| vite.config.js.timestamp-* | vite.config.js.timestamp-* | ||||||
| vite.config.ts.timestamp-* | vite.config.ts.timestamp-* | ||||||
|  | .unlighthouse | ||||||
							
								
								
									
										27
									
								
								backend/Dockerfile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								backend/Dockerfile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | FROM alpine:3.19.1 | ||||||
|  | 
 | ||||||
|  | RUN addgroup -S nonroot \ | ||||||
|  |     && adduser -S nonroot -G nonroot | ||||||
|  | 
 | ||||||
|  | USER nonroot | ||||||
|  | 
 | ||||||
|  | ARG PB_VERSION=0.21.3 | ||||||
|  | 
 | ||||||
|  | RUN apk add --no-cache \ | ||||||
|  |     unzip \ | ||||||
|  |     ca-certificates | ||||||
|  | 
 | ||||||
|  | # download and unzip PocketBase | ||||||
|  | ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip /tmp/pb.zip | ||||||
|  | RUN unzip /tmp/pb.zip -d /pb/ | ||||||
|  | 
 | ||||||
|  | # uncomment to copy the local pb_migrations dir into the image | ||||||
|  | COPY ./pb_migrations /pb/pb_migrations | ||||||
|  | 
 | ||||||
|  | # uncomment to copy the local pb_hooks dir into the image | ||||||
|  | # COPY ./pb_hooks /pb/pb_hooks | ||||||
|  | 
 | ||||||
|  | EXPOSE 8080 | ||||||
|  | 
 | ||||||
|  | # start PocketBase | ||||||
|  | CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8080"] | ||||||
|  | @ -9,7 +9,8 @@ | ||||||
| 		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | 		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | ||||||
| 		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | 		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | ||||||
| 		"lint": "prettier --check . && eslint .", | 		"lint": "prettier --check . && eslint .", | ||||||
| 		"format": "prettier --write ." | 		"format": "prettier --write .", | ||||||
|  | 		"unlighthouse": "unlighthouse-ci" | ||||||
| 	}, | 	}, | ||||||
| 	"devDependencies": { | 	"devDependencies": { | ||||||
| 		"@sveltejs/adapter-auto": "^3.0.0", | 		"@sveltejs/adapter-auto": "^3.0.0", | ||||||
|  | @ -33,6 +34,7 @@ | ||||||
| 		"tailwindcss": "^3.3.6", | 		"tailwindcss": "^3.3.6", | ||||||
| 		"tslib": "^2.4.1", | 		"tslib": "^2.4.1", | ||||||
| 		"typescript": "^5.0.0", | 		"typescript": "^5.0.0", | ||||||
|  | 		"unlighthouse": "^0.10.6", | ||||||
| 		"vite": "^5.0.3", | 		"vite": "^5.0.3", | ||||||
| 		"zod": "^3.22.4" | 		"zod": "^3.22.4" | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
							
								
								
									
										3005
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										3005
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,9 +1,9 @@ | ||||||
| export { default as Metadata } from './metadata.svelte'; | export { default as Metadata } from './metadata.svelte'; | ||||||
| export { default as SiteFooter } from './site-footer.svelte'; | export { default as SiteFooter } from './site-footer.svelte'; | ||||||
|  | export { default as UserNav } from './user-nav.svelte'; | ||||||
| export { default as SiteNavBar } from './site-navbar.svelte'; | export { default as SiteNavBar } from './site-navbar.svelte'; | ||||||
| export { default as TailwindIndicator } from './tailwind-indicator.svelte'; | export { default as TailwindIndicator } from './tailwind-indicator.svelte'; | ||||||
| export { default as ModeToggle } from './mode-toggle.svelte'; | export { default as ModeToggle } from './mode-toggle.svelte'; | ||||||
| export { default as Particles } from './particles.svelte'; | export { default as Particles } from './particles.svelte'; | ||||||
| 
 | 
 | ||||||
| export * from './icons'; | export * from './icons'; | ||||||
| export * from './nav'; |  | ||||||
|  |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| export { default as MainNav } from './main-nav.svelte'; |  | ||||||
| export { default as MobileNav } from './mobile-nav.svelte'; |  | ||||||
|  | @ -1,25 +0,0 @@ | ||||||
| <script lang="ts"> |  | ||||||
| 	import { page } from '$app/stores'; |  | ||||||
| 	import { cn } from '$lib/utils'; |  | ||||||
| 	import { navConfig } from '$lib/config/nav'; |  | ||||||
| 
 |  | ||||||
| 	export let authenticated = false; |  | ||||||
| </script> |  | ||||||
| 
 |  | ||||||
| <div class="mr-4 hidden md:flex"> |  | ||||||
| 	<nav class="flex items-center space-x-6 text-sm font-medium"> |  | ||||||
| 		{#each navConfig.mainNav as navItem, index (navItem + index.toString())} |  | ||||||
| 			{#if navItem.href && (navItem.auth == authenticated || navItem.always)} |  | ||||||
| 				<a |  | ||||||
| 					href={navItem.href} |  | ||||||
| 					class={cn( |  | ||||||
| 						'transition-colors hover:text-foreground/80', |  | ||||||
| 						$page.url.pathname === navItem.href ? 'text-foreground' : 'text-foreground/60' |  | ||||||
| 					)} |  | ||||||
| 				> |  | ||||||
| 					{navItem.title} |  | ||||||
| 				</a> |  | ||||||
| 			{/if} |  | ||||||
| 		{/each} |  | ||||||
| 	</nav> |  | ||||||
| </div> |  | ||||||
|  | @ -1,23 +0,0 @@ | ||||||
| <script lang="ts"> |  | ||||||
| 	import { page } from '$app/stores'; |  | ||||||
| 	import { cn } from '$lib/utils'; |  | ||||||
| 
 |  | ||||||
| 	export let href: string; |  | ||||||
| 	export let open: boolean; |  | ||||||
| 
 |  | ||||||
| 	let className: string | undefined | null = undefined; |  | ||||||
| 	export { className as class }; |  | ||||||
| </script> |  | ||||||
| 
 |  | ||||||
| <a |  | ||||||
| 	{href} |  | ||||||
| 	on:click={() => (open = false)} |  | ||||||
| 	class={cn( |  | ||||||
| 		$page.url.pathname === href ? 'text-foreground' : 'text-foreground/60', |  | ||||||
| 		'hover:text-foreground', |  | ||||||
| 		className |  | ||||||
| 	)} |  | ||||||
| 	{...$$restProps} |  | ||||||
| > |  | ||||||
| 	<slot /> |  | ||||||
| </a> |  | ||||||
|  | @ -1,68 +0,0 @@ | ||||||
| <script lang="ts"> |  | ||||||
| 	import * as Sheet from '$lib/components/ui/sheet/'; |  | ||||||
| 	import { HamburgerMenu } from 'radix-icons-svelte'; |  | ||||||
| 	import { Button } from '$lib/components/ui/button'; |  | ||||||
| 	import { navConfig } from '$lib/config/nav'; |  | ||||||
| 	import { siteConfig } from '$lib/config/site'; |  | ||||||
| 	import { Icons } from '../icons'; |  | ||||||
| 	import MobileLink from './mobile-link.svelte'; |  | ||||||
| 
 |  | ||||||
| 	let open = false; |  | ||||||
| 	export let authenticated = false; |  | ||||||
| </script> |  | ||||||
| 
 |  | ||||||
| <Sheet.Root bind:open> |  | ||||||
| 	<Sheet.Trigger asChild let:builder> |  | ||||||
| 		<Button |  | ||||||
| 			builders={[builder]} |  | ||||||
| 			variant="ghost" |  | ||||||
| 			class="mr-2 px-0 text-base hover:bg-transparent focus-visible:bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 md:hidden" |  | ||||||
| 		> |  | ||||||
| 			<HamburgerMenu class="h-5 w-5" /> |  | ||||||
| 			<span class="sr-only">Toggle Menu</span> |  | ||||||
| 		</Button> |  | ||||||
| 	</Sheet.Trigger> |  | ||||||
| 	<Sheet.Content side="right" class="pr-0"> |  | ||||||
| 		<MobileLink href="/" class="flex items-center" bind:open> |  | ||||||
| 			<span class="sr-only">Logo icon (return home)</span> |  | ||||||
| 			<div class="mr-4 rounded-sm bg-gray-950 p-0.5 dark:bg-transparent"> |  | ||||||
| 				<Icons.logo /> |  | ||||||
| 			</div> |  | ||||||
| 			<span class="font-mono font-bold tracking-tighter">{siteConfig.name}</span> |  | ||||||
| 		</MobileLink> |  | ||||||
| 		<div class="my-4 h-[calc(100vh-8rem)] overflow-auto pl-1 pt-10"> |  | ||||||
| 			<div class="flex flex-col space-y-3"> |  | ||||||
| 				{#each navConfig.mainNav as navItem, index (navItem + index.toString())} |  | ||||||
| 					{#if navItem.href && (navItem.auth == authenticated || navItem.always)} |  | ||||||
| 						<MobileLink href={navItem.href} bind:open class="pt-2 text-5xl font-bold"> |  | ||||||
| 							{navItem.title} |  | ||||||
| 						</MobileLink> |  | ||||||
| 					{/if} |  | ||||||
| 				{/each} |  | ||||||
| 			</div> |  | ||||||
| 			<div class="flex flex-col space-y-2"> |  | ||||||
| 				{#each navConfig.sidebarNav as navItem, index (index)} |  | ||||||
| 					<div class="flex flex-col space-y-3 pt-6"> |  | ||||||
| 						<h4 class="font-medium">{navItem.title}</h4> |  | ||||||
| 						{#if navItem?.items?.length} |  | ||||||
| 							{#each navItem.items as item} |  | ||||||
| 								{#if !item.disabled && item.href} |  | ||||||
| 									<MobileLink href={item.href} bind:open class="text-muted-foreground"> |  | ||||||
| 										{item.title} |  | ||||||
| 										{#if item.label} |  | ||||||
| 											<span |  | ||||||
| 												class="ml-2 rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000]" |  | ||||||
| 											> |  | ||||||
| 												{item.label} |  | ||||||
| 											</span> |  | ||||||
| 										{/if} |  | ||||||
| 									</MobileLink> |  | ||||||
| 								{/if} |  | ||||||
| 							{/each} |  | ||||||
| 						{/if} |  | ||||||
| 					</div> |  | ||||||
| 				{/each} |  | ||||||
| 			</div> |  | ||||||
| 		</div> |  | ||||||
| 	</Sheet.Content> |  | ||||||
| </Sheet.Root> |  | ||||||
|  | @ -5,8 +5,10 @@ | ||||||
| <footer class="container py-6"> | <footer class="container py-6"> | ||||||
| 	<div class="space-y-1"> | 	<div class="space-y-1"> | ||||||
| 		<p class="text-center text-sm text-muted-foreground"> | 		<p class="text-center text-sm text-muted-foreground"> | ||||||
| 			© {new Date().getFullYear()} — {siteConfig.name} by {siteConfig.author}. Licensed | 			© {new Date().getFullYear()} — | ||||||
| 			under GPL-3.0. | 			<a href={siteConfig.links.gitHubProject} target="_blank">{siteConfig.name}</a> | ||||||
|  | 			by <a href={siteConfig.links.gitHubProfile} target="_blank">{siteConfig.author}</a>. Licensed | ||||||
|  | 			GPL-3.0. | ||||||
| 		</p> | 		</p> | ||||||
| 	</div> | 	</div> | ||||||
| </footer> | </footer> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| 	import { Icons, ModeToggle, MainNav, MobileNav } from '$lib/components/site'; | 	import { Icons, ModeToggle, UserNav } from '$lib/components/site'; | ||||||
| 	import { siteConfig } from '$lib/config/site'; | 	import { siteConfig } from '$lib/config/site'; | ||||||
| 	import UserNav from './nav/user-nav.svelte'; |  | ||||||
| 
 | 
 | ||||||
| 	export let authenticated = false; | 	export let authenticated = false; | ||||||
| 	export let user: object | null = null; | 	export let user: object | null = null; | ||||||
|  | @ -18,11 +17,11 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 			<span class="text-xl font-bold tracking-tight">{siteConfig.name}</span> | 			<span class="text-xl font-bold tracking-tight">{siteConfig.name}</span> | ||||||
| 		</a> | 		</a> | ||||||
| 		<MainNav {authenticated} /> |  | ||||||
| 		<div class="flex flex-1 items-center justify-end space-x-2 sm:space-x-4"> | 		<div class="flex flex-1 items-center justify-end space-x-2 sm:space-x-4"> | ||||||
|  | 			{#if !authenticated} | ||||||
| 				<ModeToggle /> | 				<ModeToggle /> | ||||||
|  | 			{/if} | ||||||
| 			<UserNav {authenticated} {user} /> | 			<UserNav {authenticated} {user} /> | ||||||
| 			<MobileNav {authenticated} /> |  | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| </header> | </header> | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ | ||||||
| 				</div> | 				</div> | ||||||
| 			</DropdownMenu.Label> | 			</DropdownMenu.Label> | ||||||
| 			<DropdownMenu.Separator /> | 			<DropdownMenu.Separator /> | ||||||
| 			<DropdownMenu.Item>Dashboards</DropdownMenu.Item> | 			<DropdownMenu.Item href="/dashboard">Dashboards</DropdownMenu.Item> | ||||||
| 			<DropdownMenu.Item>Connectors</DropdownMenu.Item> | 			<DropdownMenu.Item>Connectors</DropdownMenu.Item> | ||||||
| 			<DropdownMenu.Separator /> | 			<DropdownMenu.Separator /> | ||||||
| 			<DropdownMenu.Label class="text-xs leading-none text-muted-foreground"> | 			<DropdownMenu.Label class="text-xs leading-none text-muted-foreground"> | ||||||
|  | @ -1,17 +0,0 @@ | ||||||
| import type { NavItem, SidebarNavItem } from '$lib/types/nav'; |  | ||||||
| 
 |  | ||||||
| interface NavConfig { |  | ||||||
| 	mainNav: NavItem[]; |  | ||||||
| 	sidebarNav: SidebarNavItem[]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const navConfig: NavConfig = { |  | ||||||
| 	mainNav: [ |  | ||||||
| 		{ |  | ||||||
| 			title: 'Dashboard', |  | ||||||
| 			href: '/dashboard', |  | ||||||
| 			auth: true |  | ||||||
| 		} |  | ||||||
| 	], |  | ||||||
| 	sidebarNav: [] |  | ||||||
| }; |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|  | 	import { browser } from '$app/environment'; | ||||||
| 	import { enhance } from '$app/forms'; | 	import { enhance } from '$app/forms'; | ||||||
| 	import { Icons } from '$lib/components/site/icons'; | 	import { Icons } from '$lib/components/site/icons'; | ||||||
| 	import { Button } from '$lib/components/ui/button'; | 	import { Button } from '$lib/components/ui/button'; | ||||||
|  | @ -40,11 +41,17 @@ | ||||||
| 			console.error(err); | 			console.error(err); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	let tab: string = 'login'; | ||||||
|  | 
 | ||||||
|  | 	if (browser) { | ||||||
|  | 		const urlSearchParams = new URLSearchParams(window.location.search); | ||||||
|  | 		tab = urlSearchParams.get('tab') || 'login'; | ||||||
|  | 	} | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <div class="lg:p-8"> | <div class="lg:p-8"> | ||||||
| 	<Tabs.Root | 	<Tabs.Root | ||||||
| 		value={form?.showLogin ? 'login' : undefined} | 		value={form?.showLogin ? 'login' : tab} | ||||||
| 		class="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]" | 		class="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]" | ||||||
| 	> | 	> | ||||||
| 		<Tabs.List class="grid w-full grid-cols-2"> | 		<Tabs.List class="grid w-full grid-cols-2"> | ||||||
|  | @ -74,7 +81,7 @@ | ||||||
| 						<div class="grid gap-2"> | 						<div class="grid gap-2"> | ||||||
| 							<Label for="email">Email or username</Label> | 							<Label for="email">Email or username</Label> | ||||||
| 							<Input | 							<Input | ||||||
| 								id="email" | 								id="email-login" | ||||||
| 								name="email" | 								name="email" | ||||||
| 								type="email" | 								type="email" | ||||||
| 								autocapitalize="none" | 								autocapitalize="none" | ||||||
|  | @ -85,7 +92,7 @@ | ||||||
| 						</div> | 						</div> | ||||||
| 						<div class="grid gap-2"> | 						<div class="grid gap-2"> | ||||||
| 							<Label for="password">Password</Label> | 							<Label for="password">Password</Label> | ||||||
| 							<Input id="password" name="password" type="password" disabled={isLoading} /> | 							<Input id="password-login" name="password" type="password" disabled={isLoading} /> | ||||||
| 						</div> | 						</div> | ||||||
| 						<Button type="submit" disabled={isLoading}> | 						<Button type="submit" disabled={isLoading}> | ||||||
| 							{#if isLoading} | 							{#if isLoading} | ||||||
|  | @ -131,7 +138,7 @@ | ||||||
| 						<div class="grid gap-2"> | 						<div class="grid gap-2"> | ||||||
| 							<Label for="email">Email</Label> | 							<Label for="email">Email</Label> | ||||||
| 							<Input | 							<Input | ||||||
| 								id="email" | 								id="email-register" | ||||||
| 								name="email" | 								name="email" | ||||||
| 								type="email" | 								type="email" | ||||||
| 								autocapitalize="none" | 								autocapitalize="none" | ||||||
|  | @ -142,11 +149,16 @@ | ||||||
| 						</div> | 						</div> | ||||||
| 						<div class="grid gap-2"> | 						<div class="grid gap-2"> | ||||||
| 							<Label for="password">Password</Label> | 							<Label for="password">Password</Label> | ||||||
| 							<Input id="password" name="password" type="password" disabled={isLoading} /> | 							<Input id="password-register" name="password" type="password" disabled={isLoading} /> | ||||||
| 						</div> | 						</div> | ||||||
| 						<div class="grid gap-2"> | 						<div class="grid gap-2"> | ||||||
| 							<Label for="password">Confirm password</Label> | 							<Label for="password">Confirm password</Label> | ||||||
| 							<Input id="password" name="passwordConfirm" type="password" disabled={isLoading} /> | 							<Input | ||||||
|  | 								id="confirm-password-register" | ||||||
|  | 								name="passwordConfirm" | ||||||
|  | 								type="password" | ||||||
|  | 								disabled={isLoading} | ||||||
|  | 							/> | ||||||
| 						</div> | 						</div> | ||||||
| 						<Button type="submit" disabled={isLoading}> | 						<Button type="submit" disabled={isLoading}> | ||||||
| 							{#if isLoading} | 							{#if isLoading} | ||||||
|  | @ -165,6 +177,11 @@ | ||||||
| 				</form> | 				</form> | ||||||
| 			</div> | 			</div> | ||||||
| 		</Tabs.Content> | 		</Tabs.Content> | ||||||
|  | 		<p class="px-8 text-center text-xs text-muted-foreground"> | ||||||
|  | 			Don't have an account? <a class="text-primary underline" href="/auth?tab=register">Register</a | ||||||
|  | 			>.<br /> | ||||||
|  | 			Forgot password? <a class="text-primary underline" href="/reset-password">Reset password.</a> | ||||||
|  | 		</p> | ||||||
| 		{#if providers.length} | 		{#if providers.length} | ||||||
| 			<form | 			<form | ||||||
| 				method="POST" | 				method="POST" | ||||||
|  | @ -252,9 +269,4 @@ | ||||||
| 			</form> | 			</form> | ||||||
| 		{/if} | 		{/if} | ||||||
| 	</Tabs.Root> | 	</Tabs.Root> | ||||||
| 
 |  | ||||||
| 	<p class="px-8 py-2 text-center text-xs text-muted-foreground"> |  | ||||||
| 		Don't have an account? <a class="text-primary underline" href="/register">Sign up.</a> <br /> |  | ||||||
| 		Forgot password? <a class="text-primary underline" href="/reset-password">Reset password.</a> |  | ||||||
| 	</p> |  | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								unlighthouse.config.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								unlighthouse.config.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | import { defineConfig } from 'unlighthouse'; | ||||||
|  | 
 | ||||||
|  | export default defineConfig({ | ||||||
|  | 	site: process.env.SCAN_URL || 'http://localhost:5173/', | ||||||
|  | 	cookies: [ | ||||||
|  | 		{ | ||||||
|  | 			name: 'pb_auth', | ||||||
|  | 			value: process.env.AUTH_COOKIE || '', | ||||||
|  | 			domain: process.env.SCAN_URL || 'http://localhost:5173/', | ||||||
|  | 			path: '/', | ||||||
|  | 			sameSite: 'Lax' | ||||||
|  | 		} | ||||||
|  | 	], | ||||||
|  | 	ci: { | ||||||
|  | 		reporter: 'jsonExpanded', | ||||||
|  | 		buildStatic: true | ||||||
|  | 	} | ||||||
|  | }); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue