+52
server.js
+52
server.js
···
81
81
res.json(status);
82
82
});
83
83
84
+
app.get("/oauth/callback", async (req, res) => {
85
+
if (!req.query.code || req.query.state !== req.session.oauthState) {
86
+
return res.status(400).send("Invalid state or missing code");
87
+
}
88
+
89
+
try {
90
+
// Exchange code for tokens
91
+
const tokenResponse = await fetch("https://bsky.social/oauth/token", {
92
+
method: "POST",
93
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
94
+
body: new URLSearchParams({
95
+
grant_type: "authorization_code",
96
+
code: req.query.code,
97
+
redirect_uri: REDIRECT_URI,
98
+
client_id: CLIENT_ID,
99
+
}),
100
+
});
101
+
102
+
if (!tokenResponse.ok)
103
+
throw new Error(`Token error: ${await tokenResponse.text()}`);
104
+
105
+
const tokens = await tokenResponse.json();
106
+
console.log("Tokens received:", {
107
+
did: tokens.did,
108
+
hasAccess: !!tokens.access_token,
109
+
});
110
+
111
+
// Log in with the access token
112
+
const agent = new BskyAgent({ service: "https://bsky.social" });
113
+
await agent.login({
114
+
identifier: tokens.did,
115
+
password: tokens.access_token,
116
+
});
117
+
118
+
// Save to session
119
+
req.session.did = agent.did;
120
+
req.session.handle = agent.session?.data?.handle || tokens.did;
121
+
req.session.accessJwt = tokens.access_token;
122
+
req.session.refreshJwt = tokens.refresh_token;
123
+
124
+
console.log("Logged in as @" + req.session.handle);
125
+
res.redirect("/");
126
+
} catch (err) {
127
+
console.error("OAuth callback failed:", err);
128
+
res.status(500).send("Login failed — check logs");
129
+
}
130
+
});
131
+
132
+
app.get("/logout", (req, res) => {
133
+
req.session.destroy(() => res.redirect("/"));
134
+
});
135
+
84
136
const PORT = process.env.PORT || 3000;
85
137
app.listen(PORT, () => {
86
138
console.log(`atstatus.net → http://localhost:${PORT}`);
+4
-4
views/layout.ejs
+4
-4
views/layout.ejs
···
10
10
<header class="header">
11
11
<div class="container">
12
12
<a href="/" class="status">@status</a>
13
-
<% if (session && session.did) { %>
14
-
<span style="opacity:0.8;">@<%= session.handle %></span>
15
-
<a href="/logout" class="login-btn">Logout</a>
13
+
<% if (session && session.handle) { %>
14
+
<span style="opacity:0.8;">@<%= session.handle %></span>
15
+
<a href="/logout" class="login-btn">Logout</a>
16
16
<% } else { %>
17
-
<a href="/login" class="login-btn">Login</a>
17
+
<a href="/login" class="login-btn">Login</a>
18
18
<% } %>
19
19
</div>
20
20
</header>