Graphical PDS migrator for AT Protocol

auth middleware

Changed files
+30 -27
islands
routes
-16
islands/Counter.tsx
··· 1 - import type { Signal } from "@preact/signals"; 2 - import { Button } from "../components/Button.tsx"; 3 - 4 - interface CounterProps { 5 - count: Signal<number>; 6 - } 7 - 8 - export default function Counter(props: CounterProps) { 9 - return ( 10 - <div class="flex gap-8 py-6"> 11 - <Button onClick={() => props.count.value -= 1}>-1</Button> 12 - <p class="text-3xl tabular-nums">{props.count}</p> 13 - <Button onClick={() => props.count.value += 1}>+1</Button> 14 - </div> 15 - ); 16 - }
+3 -2
islands/CredLogin.tsx
··· 1 1 import { useState } from 'preact/hooks' 2 2 import { JSX } from 'preact' 3 + import { LoginProps } from "./LoginSelector.tsx"; 3 4 4 - export default function CredLogin() { 5 + export default function CredLogin({ redirect }: LoginProps) { 5 6 const [handle, setHandle] = useState('') 6 7 const [password, setPassword] = useState('') 7 8 const [error, setError] = useState<string | null>(null) ··· 32 33 await new Promise((resolve) => setTimeout(resolve, 500)) 33 34 34 35 // Redirect to home page after successful login 35 - globalThis.location.href = '/' 36 + globalThis.location.href = '/login/callback?redirect=' + encodeURIComponent(redirect) 36 37 } catch (err) { 37 38 const message = err instanceof Error ? err.message : 'Login failed' 38 39 setError(message)
+5 -3
islands/Ticket.tsx
··· 63 63 </p> 64 64 <p> 65 65 Think you might need to migrate in the future but your PDS might be 66 - hostile or offline? No worries! You can head to the ticket booth and 67 - get a PLC key free of charge and use it for account recovery in the 68 - future. You can also go to baggage claim (take the air shuttle to 66 + hostile or offline? No worries! Soon you'll be able to go to the 67 + ticket booth and get a PLC key free of charge and use it for account 68 + recovery in the future. You can also go to baggage claim (take the air 69 + shuttle to terminal four) and get a downloadable backup of all your 70 + current PDS data in case that were to happen. 69 71 terminal four) and get a downloadable backup of all your current PDS 70 72 data in case that were to happen. 71 73 </p>
+17 -3
main.ts
··· 8 8 app.use(staticFiles()); 9 9 10 10 // this can also be defined via a file. feel free to delete this! 11 - const exampleLoggerMiddleware = define.middleware((ctx) => { 12 - console.log(`${ctx.req.method} ${ctx.req.url}`); 11 + const authMiddleware = define.middleware(async (ctx) => { 12 + const url = new URL(ctx.req.url); 13 + if (url.pathname.startsWith("/migrate")) { 14 + ctx.state.auth = true 15 + } 16 + if (ctx.state.auth) { 17 + const me = await fetch(`${url.origin}/api/me`, { 18 + credentials: "include", 19 + }); 20 + const json = await me.json(); 21 + if (json !== null && json.did) { 22 + return ctx.next(); 23 + } else { 24 + return ctx.redirect("/login"); 25 + } 26 + } 13 27 return ctx.next(); 14 28 }); 15 - app.use(exampleLoggerMiddleware); 29 + app.use(authMiddleware); 16 30 17 31 await fsRoutes(app, { 18 32 loadIsland: (path) => import(`./islands/${path}`),
+1 -1
routes/index.tsx
··· 28 28 /> 29 29 </div> 30 30 <p class="font-mono text-lg sm:text-xl mb-4 mt-4 sm:mb-6 mt-0 text-center text-gray-600 dark:text-gray-300"> 31 - Airport is made with love by <a class="text-blue-500 hover:underline" href="https://bsky.app/profile/knotbin.com">Roscoe</a> in collaboration with <a class="text-blue-500 hover:underline" href="https://sprk.so">Spark</a>. 31 + Airport is made with love by <a class="text-blue-500 hover:underline" href="https://bsky.app/profile/knotbin.com">Roscoe</a> for <a class="text-blue-500 hover:underline" href="https://sprk.so">Spark</a>, a new short-video platform for AT Protocol. 32 32 </p> 33 33 <SocialLinks /> 34 34 </div>
+4 -2
utils.ts
··· 1 1 import { createDefine } from "fresh"; 2 2 3 - // deno-lint-ignore no-empty-interface 4 - export interface State {} 3 + export interface State { 4 + title?: string; 5 + auth: boolean; 6 + } 5 7 6 8 export const define = createDefine<State>();