char-slop/stars.hackery.site

git clone https://git.t4t.associates/char-slop/stars.hackery.site

Charlotte Somsyntactic pass: no casts, assertions, or void92004f9

main
3.9 KiB117 linesraw
1import { assert, assertEquals } from "@std/assert";
2import { DatabaseSync } from "node:sqlite";
3import { Auth, type Session } from "./auth.ts";
4import { type Actor, Hydrant } from "./hydrant.ts";
5import { handler } from "./main.ts";
6import { Star } from "./records.ts";
7import { Index } from "./sync.ts";
8import { TitleLookup } from "./title.ts";
9
10Deno.test("public profile escapes comments and shows handle rather than display name", async () => {
11  const db = new DatabaseSync(":memory:");
12  try {
13    const auth = new Auth(db, new URL("http://127.0.0.1:8000"));
14    const hydrant = new class extends Hydrant {
15      override actor(_identifier: string): Promise<Actor> {
16        return Promise.resolve({
17          did: "did:plc:abcdefgh",
18          handle: "char.lt",
19          pds: "https://pds.example.org/",
20          avatar: "https://pds.example.org/avatar",
21        });
22      }
23      override stars(_did: string, _cursor?: string) {
24        return Promise.resolve({
25          stars: [{
26            uri: "at://did:plc:abcdefgh/site.hackery.stars.star/3mgabcdefghij",
27            link: "https://example.com/",
28            star: Star.build({
29              url: "https://example.com/",
30              title: "A useful project",
31              comment: "<script>alert(1)</script>",
32              createdAt: "2026-09-24T10:00:00Z",
33            }),
34          }],
35          cursor: undefined,
36        });
37      }
38    }(new URL("http://127.0.0.1:3000"));
39    const index = new Index(db, hydrant);
40    const res = await handler(new Request("http://127.0.0.1:8000/char.lt"), {
41      auth,
42      hydrant,
43      index,
44      titles: new TitleLookup(db),
45    });
46    assertEquals(res.status, 200);
47    const body = await res.text();
48    assert(body.includes("char.lt"));
49    assert(body.includes(">A useful project</a>"));
50    assert(body.includes(">example.com</small>"));
51    assert(body.includes("Starred: 24 September 2026 at 10:00"));
52    assert(body.includes("&lt;script&gt;alert(1)&lt;/script&gt;"));
53    assert(!body.includes("<script>"));
54    assert(!body.includes("displayName"));
55  } finally {
56    db.close();
57  }
58});
59
60Deno.test("unverified handle is shown with a readable DID profile URL", async () => {
61  const db = new DatabaseSync(":memory:");
62  try {
63    const auth = new Auth(db, new URL("http://127.0.0.1:8000"));
64    const hydrant = new class extends Hydrant {
65      override actor(_identifier: string): Promise<Actor> {
66        return Promise.resolve({
67          did: "did:plc:abcdefgh",
68          handle: "claimed.example.com",
69          handleVerified: false,
70          pds: "https://pds.example.org/",
71        });
72      }
73      override stars(_did: string, _cursor?: string) {
74        return Promise.resolve({ stars: [], cursor: undefined });
75      }
76    }(new URL("http://127.0.0.1:3000"));
77    auth.session = () =>
78      Promise.resolve({
79        id: "test-session",
80        did: "did:plc:abcdefgh",
81        csrf: "test-csrf",
82        oauth: {},
83      } as unknown as Session);
84    const app = {
85      auth,
86      hydrant,
87      index: new Index(db, hydrant),
88      titles: new TitleLookup(db),
89    };
90    const profile = await handler(
91      new Request("http://127.0.0.1:8000/did:plc:abcdefgh"),
92      app,
93    );
94    assertEquals(profile.status, 200);
95    const body = await profile.text();
96    assert(body.includes("claimed.example.com"));
97    assert(body.includes("(unverified)"));
98    assert(
99      body.includes(
100        '<nav><a href="/share">Add Star</a><a href="/did:plc:abcdefgh">claimed.example.com</a></nav>',
101      ),
102    );
103    assert(!body.includes('href="/login">Sign in</a>'));
104    const signIn = await handler(
105      new Request("http://127.0.0.1:8000/login"),
106      app,
107    );
108    assertEquals(signIn.headers.get("location"), "/");
109    const browse = await handler(
110      new Request("http://127.0.0.1:8000/go?handle=did%3Aplc%3Aabcdefgh"),
111      app,
112    );
113    assertEquals(browse.headers.get("location"), "/did:plc:abcdefgh");
114  } finally {
115    db.close();
116  }
117});