···
34
+
res.setHeader('Vary', 'Cookie')
const session = await getIronSession<Session>(req, res, {
password: env.COOKIE_SECRET,
if (!session.did) return null
42
+
// This page is dynamic and should not be cached publicly
43
+
res.setHeader('cache-control', `max-age=${MAX_AGE}, private`)
const oauthSession = await ctx.oauthClient.restore(session.did)
return oauthSession ? new Agent(oauthSession) : null
···
'/oauth-client-metadata.json',
63
-
handler((req: Request, res: Response) => {
69
+
handler((req, res) => {
res.setHeader('cache-control', `max-age=${MAX_AGE}, public`)
res.json(ctx.oauthClient.clientMetadata)
···
'/.well-known/jwks.json',
72
-
handler((req: Request, res: Response) => {
78
+
handler((req, res) => {
res.setHeader('cache-control', `max-age=${MAX_AGE}, public`)
res.json(ctx.oauthClient.jwks)
···
// OAuth callback to complete session creation
81
-
handler(async (req: Request, res: Response) => {
87
+
handler(async (req, res) => {
res.setHeader('cache-control', 'no-store')
const params = new URLSearchParams(req.originalUrl.split('?')[1])
···
119
-
handler(async (req: Request, res: Response) => {
125
+
handler(async (req, res) => {
res.setHeader('cache-control', `max-age=${MAX_AGE}, public`)
122
-
return res.type('html').send(page(login({})))
127
+
res.type('html').send(page(login({})))
···
130
-
handler(async (req: Request, res: Response) => {
135
+
handler(async (req, res) => {
136
+
// Never store this route
res.setHeader('cache-control', 'no-store')
133
-
const input = ifString(req.body.input)
137
-
return res.type('html').send(page(login({ error: 'invalid input' })))
140
-
// @NOTE "input" can be a handle, a DID or a service URL (PDS).
// Initiate the OAuth flow
141
+
// Validate input: can be a handle, a DID or a service URL (PDS).
142
+
const input = ifString(req.body.input)
144
+
throw new Error('Invalid input')
147
+
// Initiate the OAuth flow
const url = await ctx.oauthClient.authorize(input, {
scope: 'atproto transition:generic',
res.redirect(url.toString())
ctx.logger.error({ err }, 'oauth authorize failed')
152
-
err instanceof OAuthResolverError
154
-
: "couldn't initiate login"
156
+
const error = err instanceof Error ? err.message : 'unexpected error'
return res.type('html').send(page(login({ error })))
···
164
-
handler(async (req: Request, res: Response) => {
166
+
handler(async (req, res) => {
res.setHeader('cache-control', `max-age=${MAX_AGE}, public`)
···
192
-
handler(async (req: Request, res: Response) => {
194
+
handler(async (req, res) => {
// Never store this route
res.setHeader('cache-control', 'no-store')
···
220
-
handler(async (req: Request, res: Response) => {
221
-
// Prevent caching of this page when the credentials change
222
-
res.setHeader('Vary', 'Cookie')
222
+
handler(async (req, res) => {
// If the user is signed in, get an agent which communicates with their server
const agent = await getSessionAgent(req, res, ctx)
···
return res.type('html').send(page(home({ statuses, didHandleMap })))
253
-
// Make sure this page does not get cached in public caches (proxies)
254
-
res.setHeader('cache-control', 'private')
// Fetch additional information about the logged-in user
const profileResponse = await agent.com.atproto.repo
···
285
-
handler(async (req: Request, res: Response) => {
286
-
// Never store this route
287
-
res.setHeader('cache-control', 'no-store')
281
+
handler(async (req, res) => {
// If the user is signed in, get an agent which communicates with their server
const agent = await getSessionAgent(req, res, ctx)
···
.send('<h1>Error: Session required</h1>')
298
-
// Construct & validate their status record
299
-
const rkey = TID.nextStr()
291
+
// Construct their status record
$type: 'xyz.statusphere.status',
status: req.body?.status,
···
const res = await agent.com.atproto.repo.putRecord({
collection: 'xyz.statusphere.status',
312
+
rkey: TID.nextStr(),