diff --git a/apps/blog-next/app/api/auth/workos/callback/route.ts b/apps/blog-next/app/api/auth/workos/callback/route.ts
new file mode 100644
index 00000000..ac9510e8
--- /dev/null
+++ b/apps/blog-next/app/api/auth/workos/callback/route.ts
@@ -0,0 +1,10 @@
+import { completeWorkosAuth } from '@holo-js/auth-workos'
+
+export async function GET(request: Request) {
+ const result = await completeWorkosAuth(request)
+ if (!result.ok) {
+ return Response.redirect(new URL(`/login?error=${encodeURIComponent(result.code)}`, request.url))
+ }
+
+ return Response.redirect(new URL('/admin', request.url))
+}
diff --git a/apps/blog-next/app/api/auth/workos/login/route.ts b/apps/blog-next/app/api/auth/workos/login/route.ts
new file mode 100644
index 00000000..3839061c
--- /dev/null
+++ b/apps/blog-next/app/api/auth/workos/login/route.ts
@@ -0,0 +1,5 @@
+import { loginWithWorkos } from '@holo-js/auth-workos'
+
+export async function GET(request: Request) {
+ return await loginWithWorkos(request)
+}
diff --git a/apps/blog-next/app/api/auth/workos/logout/route.ts b/apps/blog-next/app/api/auth/workos/logout/route.ts
new file mode 100644
index 00000000..d556de00
--- /dev/null
+++ b/apps/blog-next/app/api/auth/workos/logout/route.ts
@@ -0,0 +1,10 @@
+import { logoutWithWorkos } from '@holo-js/auth-workos'
+
+export async function POST(request: Request) {
+ const result = await logoutWithWorkos(request)
+ if (!result.ok) {
+ return Response.json(result, { status: 422 })
+ }
+
+ return Response.redirect(result.url, 303)
+}
diff --git a/apps/blog-next/app/api/auth/workos/register/route.ts b/apps/blog-next/app/api/auth/workos/register/route.ts
new file mode 100644
index 00000000..93ace66f
--- /dev/null
+++ b/apps/blog-next/app/api/auth/workos/register/route.ts
@@ -0,0 +1,5 @@
+import { registerWithWorkos } from '@holo-js/auth-workos'
+
+export async function GET(request: Request) {
+ return await registerWithWorkos(request)
+}
diff --git a/apps/blog-next/app/auth-nav.tsx b/apps/blog-next/app/auth-nav.tsx
index 98ce7f72..61dcd30d 100644
--- a/apps/blog-next/app/auth-nav.tsx
+++ b/apps/blog-next/app/auth-nav.tsx
@@ -18,6 +18,10 @@ const logoutButtonStyle = {
padding: 0,
} as const
+const logoutFormStyle = {
+ display: 'inline',
+} as const
+
export function AuthNav() {
const auth = useAuth()
const [isLoggingOut, setIsLoggingOut] = useState(false)
@@ -57,6 +61,9 @@ export function AuthNav() {
<>
{displayName}
+
>
)
}
diff --git a/apps/blog-next/app/login/page.tsx b/apps/blog-next/app/login/page.tsx
index 2c396842..5b5c7f2d 100644
--- a/apps/blog-next/app/login/page.tsx
+++ b/apps/blog-next/app/login/page.tsx
@@ -47,6 +47,7 @@ export default function LoginPage() {
{:else}
Login
Register
@@ -94,6 +97,9 @@
opacity: 0.6;
pointer-events: none;
}
+ .logout-form {
+ display: inline;
+ }
a {
color: #cbd5e1;
text-decoration: none;
diff --git a/apps/blog-sveltekit/src/routes/api/auth/workos/callback/+server.ts b/apps/blog-sveltekit/src/routes/api/auth/workos/callback/+server.ts
new file mode 100644
index 00000000..a95a47b1
--- /dev/null
+++ b/apps/blog-sveltekit/src/routes/api/auth/workos/callback/+server.ts
@@ -0,0 +1,11 @@
+import { redirect, type RequestHandler } from '@sveltejs/kit'
+import { completeWorkosAuth } from '@holo-js/auth-workos'
+
+export const GET = (async (event) => {
+ const result = await completeWorkosAuth(event)
+ if (!result.ok) {
+ throw redirect(303, `/login?error=${encodeURIComponent(result.code)}`)
+ }
+
+ throw redirect(303, '/admin')
+}) satisfies RequestHandler
diff --git a/apps/blog-sveltekit/src/routes/api/auth/workos/login/+server.ts b/apps/blog-sveltekit/src/routes/api/auth/workos/login/+server.ts
new file mode 100644
index 00000000..72ccebec
--- /dev/null
+++ b/apps/blog-sveltekit/src/routes/api/auth/workos/login/+server.ts
@@ -0,0 +1,6 @@
+import { loginWithWorkos } from '@holo-js/auth-workos'
+import type { RequestHandler } from './$types'
+
+export const GET = (async (event) => {
+ return await loginWithWorkos(event)
+}) satisfies RequestHandler
diff --git a/apps/blog-sveltekit/src/routes/api/auth/workos/logout/+server.ts b/apps/blog-sveltekit/src/routes/api/auth/workos/logout/+server.ts
new file mode 100644
index 00000000..f1e93aca
--- /dev/null
+++ b/apps/blog-sveltekit/src/routes/api/auth/workos/logout/+server.ts
@@ -0,0 +1,11 @@
+import { redirect, type RequestHandler } from '@sveltejs/kit'
+import { logoutWithWorkos } from '@holo-js/auth-workos'
+
+export const POST = (async (event) => {
+ const result = await logoutWithWorkos(event)
+ if (!result.ok) {
+ return Response.json(result, { status: 422 })
+ }
+
+ throw redirect(303, result.url)
+}) satisfies RequestHandler
diff --git a/apps/blog-sveltekit/src/routes/api/auth/workos/register/+server.ts b/apps/blog-sveltekit/src/routes/api/auth/workos/register/+server.ts
new file mode 100644
index 00000000..e271c22f
--- /dev/null
+++ b/apps/blog-sveltekit/src/routes/api/auth/workos/register/+server.ts
@@ -0,0 +1,6 @@
+import { registerWithWorkos } from '@holo-js/auth-workos'
+import type { RequestHandler } from './$types'
+
+export const GET = (async (event) => {
+ return await registerWithWorkos(event)
+}) satisfies RequestHandler
diff --git a/apps/blog-sveltekit/src/routes/login/+page.svelte b/apps/blog-sveltekit/src/routes/login/+page.svelte
index 8a3523e6..4a472483 100644
--- a/apps/blog-sveltekit/src/routes/login/+page.svelte
+++ b/apps/blog-sveltekit/src/routes/login/+page.svelte
@@ -30,6 +30,7 @@