tangled
alpha
login
or
join now
dbushell.com
/
attic.social
11
fork
atom
Attic is a cozy space with lofty ambitions.
attic.social
11
fork
atom
overview
issues
pulls
pipelines
improve login
dbushell.com
5 days ago
6f9cfe42
b477365b
verified
This commit was signed with the committer's
known signature
.
dbushell.com
SSH Key Fingerprint:
SHA256:Sj5AfJ6VbC0PEnnQD2kGGEiGFwHdFBS/ypN5oifzzFI=
+46
-22
5 changed files
expand all
collapse all
unified
split
README.md
src
lib
server
session.ts
routes
+layout.svelte
+page.server.ts
svelte.config.js
+4
README.md
···
2
2
3
3
Attic is a cozy space with lofty ambitions.
4
4
5
5
+
What does Attic do? I'm still deciding... it'll probably become a random assortment of features. Right now it has bookmarks. Bookmarks will have search and tags soon.
6
6
+
7
7
+
Attic is extremely early in development! Use a your own risk :)
8
8
+
5
9
* * *
6
10
7
11
Copyright © 2026 [David Bushell](https://dbushell.com)
+23
-18
src/lib/server/session.ts
···
40
40
handle: string,
41
41
): Promise<URL> => {
42
42
if (isHandle(handle) === false) {
43
43
-
throw new Error("invalid handle");
43
43
+
throw new Error("Invalid handle.");
44
44
+
}
45
45
+
try {
46
46
+
const oAuthClient = createOAuthClient(event);
47
47
+
const { url } = await oAuthClient.authorize({
48
48
+
target: { "type": "account", identifier: handle },
49
49
+
});
50
50
+
// Temporary to remember handle across oauth flow
51
51
+
event.cookies.set(
52
52
+
HANDLE_COOKIE,
53
53
+
handle,
54
54
+
{
55
55
+
httpOnly: true,
56
56
+
maxAge: OAUTH_MAX_AGE,
57
57
+
path: "/",
58
58
+
sameSite: "lax",
59
59
+
secure: !dev,
60
60
+
},
61
61
+
);
62
62
+
return url;
63
63
+
} catch (err) {
64
64
+
console.log(err);
65
65
+
throw new Error("OAuth failed.");
44
66
}
45
45
-
const oAuthClient = createOAuthClient(event);
46
46
-
const { url } = await oAuthClient.authorize({
47
47
-
target: { "type": "account", identifier: handle },
48
48
-
});
49
49
-
// Temporary to remember handle across oauth flow
50
50
-
event.cookies.set(
51
51
-
HANDLE_COOKIE,
52
52
-
handle,
53
53
-
{
54
54
-
httpOnly: true,
55
55
-
maxAge: OAUTH_MAX_AGE,
56
56
-
path: "/",
57
57
-
sameSite: "lax",
58
58
-
secure: !dev,
59
59
-
},
60
60
-
);
61
61
-
return url;
62
67
};
63
68
64
69
/**
+6
src/routes/+layout.svelte
···
1
1
<script lang="ts">
2
2
+
import { dev } from "$app/environment";
2
3
import "$css/main.css";
3
4
import { pointer } from "$lib/dialog.svelte.js";
4
5
import { onMount } from "svelte";
5
6
6
7
onMount(() => {
8
8
+
if (dev === false) {
9
9
+
globalThis.addEventListener("load", () => {
10
10
+
navigator.serviceWorker.register("/service-worker.js");
11
11
+
});
12
12
+
}
7
13
if (pointer.ref) {
8
14
pointer.ref.showPopover();
9
15
}
+10
-4
src/routes/+page.server.ts
···
21
21
throw new Error();
22
22
}
23
23
const formData = await event.request.formData();
24
24
-
const handle = formData.get("handle");
24
24
+
let handle = String(formData.get("handle"));
25
25
+
if (handle.startsWith("@")) {
26
26
+
handle = handle.substring(1);
27
27
+
}
25
28
let url: URL;
26
29
try {
27
30
event.cookies.delete(HANDLE_COOKIE, { path: "/" });
28
28
-
url = await startSession(event, String(handle ?? ""));
31
31
+
url = await startSession(event, handle);
29
32
} catch (err) {
30
30
-
console.log(err);
31
31
-
return fail(400, { handle, action: "login", error: "Invalid handle." });
33
33
+
let message = "Login failed.";
34
34
+
if (err instanceof Error && err.message) {
35
35
+
message = err.message;
36
36
+
}
37
37
+
return fail(400, { handle, action: "login", error: message });
32
38
}
33
39
redirect(303, url);
34
40
},
+3
svelte.config.js
···
14
14
publicPrefix: "PUBLIC",
15
15
privatePrefix: "PRIVATE",
16
16
},
17
17
+
serviceWorker: {
18
18
+
register: false,
19
19
+
},
17
20
},
18
21
};
19
22