1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { twitterRequestAccessToken } from "https://esm.town/v/andreterron/twitterRequestAccessToken";
import { redirectResponse } from "https://esm.town/v/andreterron/redirectResponse";
import { nanoid } from "https://esm.town/v/stevekrouse/nanoid?v=3";
export async function twitterAuthHandler(
req: Request,
{ client_id, client_secret, redirect_uri, scopes, storage }: {
client_id: string;
client_secret: string;
redirect_uri: string;
scopes: string[];
storage?: {
state: string;
challenge: string;
};
},
): Promise<{
res: Response;
storage?: {
state: string;
challenge: string;
};
token?: {
token_type: string;
expires_in: number;
access_token: string;
scope: string;
refresh_token: string;
};
}> {
// Imports
const { Client, auth } = await import("npm:twitter-api-sdk");
//
const authClient = new auth.OAuth2User({
client_id,
client_secret,
callback: redirect_uri,
scopes: scopes as any[],
});
const client = new Client(authClient);
const reqUrl = new URL(req.url);
switch (reqUrl.pathname.replace(/\/$/, "")) {
case "": {
let challenge = await nanoid();
let state = await nanoid();
const authUrl = authClient.generateAuthURL({
state: state,
code_challenge_method: "plain",
code_challenge: challenge,
});
return {
res: redirectResponse(authUrl),
storage: {
state,
challenge,
},
};
}
case "/callback": {
const code = reqUrl.searchParams.get("code");
const state = reqUrl.searchParams.get("state");
if (state !== storage.state)
return { res: new Response("State isn't matching", { status: 500 }) };
const tokenResponse = await twitterRequestAccessToken({
code,
client_id,
client_secret,
redirect_uri,
challenge: storage.challenge,
});
// TODO: Improve result page
return { res: new Response("OK", { status: 200 }), token: tokenResponse };
}
}
return { res: new Response("Not Found", { status: 404 }) };
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
October 23, 2023