Update to respond a new access token every request
This commit is contained in:
parent
143928bd86
commit
01b70389f0
32
pages/api/icns-verification.ts
Normal file
32
pages/api/icns-verification.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { withIronSessionApiRoute } from "iron-session/next";
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
import { ironOptions } from "../../iron.config";
|
||||||
|
import { IcnsVerificationInfoResponse } from "../../types/api-response";
|
||||||
|
import { request } from "../../utils/url";
|
||||||
|
|
||||||
|
export default withIronSessionApiRoute(async function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (!process.env.ICNS_VERIFIER_URI) {
|
||||||
|
console.log(".env is not set");
|
||||||
|
return res.status(500).json({ error: "Internal server error" });
|
||||||
|
}
|
||||||
|
const icnsVerificationInfo = await request<IcnsVerificationInfoResponse>(
|
||||||
|
process.env.ICNS_VERIFIER_URI,
|
||||||
|
{
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(req.body),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
res.status(200).json(icnsVerificationInfo);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ error: "Internal server error" });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ironOptions);
|
@ -13,29 +13,39 @@ export default withIronSessionApiRoute(async function handler(
|
|||||||
!process.env.TWITTER_CLIENT_SECRET ||
|
!process.env.TWITTER_CLIENT_SECRET ||
|
||||||
!process.env.TWITTER_AUTH_CALLBACK_URI
|
!process.env.TWITTER_AUTH_CALLBACK_URI
|
||||||
) {
|
) {
|
||||||
return res
|
console.error(new Error(".env is not set"));
|
||||||
.status(500)
|
return res.status(500).send({
|
||||||
.send(
|
error:
|
||||||
"Twitter app client id or client secret or callback URI is not set",
|
"Twitter app client id or client secret or callback URI is not set",
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req.session.code_verifier) {
|
if (!req.session.code_verifier) {
|
||||||
return res.status(401).send("No OAuth2.0 code verifier");
|
return res.status(401).send({
|
||||||
|
error: "No OAuth2.0 code verifier",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
|
if (req.session.refresh_token) {
|
||||||
|
params.append("grant_type", "refresh_token");
|
||||||
|
params.append("refresh_token", req.session.refresh_token);
|
||||||
|
params.append("client_id", process.env.TWITTER_CLIENT_ID);
|
||||||
|
} else {
|
||||||
const { code, state } = req.query;
|
const { code, state } = req.query;
|
||||||
if (state !== process.env.TWITTER_AUTH_STATE) {
|
if (state !== process.env.TWITTER_AUTH_STATE) {
|
||||||
return res.status(401).send("State isn't matching");
|
return res.status(401).send({ error: "State isn't matching" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.append("grant_type", "authorization_code");
|
params.append("grant_type", "authorization_code");
|
||||||
params.append("code", code as string);
|
params.append("code", code as string);
|
||||||
params.append("redirect_uri", process.env.TWITTER_AUTH_CALLBACK_URI);
|
params.append("redirect_uri", process.env.TWITTER_AUTH_CALLBACK_URI);
|
||||||
params.append("code_verifier", req.session.code_verifier);
|
params.append("code_verifier", req.session.code_verifier);
|
||||||
const { access_token: accessToken } =
|
}
|
||||||
|
|
||||||
|
const { access_token: accessToken, refresh_token } =
|
||||||
await request<TwitterOAuth2TokenResponse>(
|
await request<TwitterOAuth2TokenResponse>(
|
||||||
`${twitterApiBaseUrl}/oauth2/token`,
|
`${twitterApiBaseUrl}/oauth2/token`,
|
||||||
{
|
{
|
||||||
@ -49,6 +59,9 @@ export default withIronSessionApiRoute(async function handler(
|
|||||||
body: params,
|
body: params,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
req.session.refresh_token = refresh_token;
|
||||||
|
await req.session.save();
|
||||||
const {
|
const {
|
||||||
data: { id, username },
|
data: { id, username },
|
||||||
} = await request<TwitterUsersMeResponse>(`${twitterApiBaseUrl}/users/me`, {
|
} = await request<TwitterUsersMeResponse>(`${twitterApiBaseUrl}/users/me`, {
|
||||||
@ -62,8 +75,8 @@ export default withIronSessionApiRoute(async function handler(
|
|||||||
username,
|
username,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.error(error);
|
||||||
res.status(500).send("Internal server error ");
|
res.status(500).json({ error: "Internal server error " });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ironOptions);
|
ironOptions);
|
||||||
|
@ -14,10 +14,12 @@ export default withIronSessionApiRoute(async function handler(
|
|||||||
res: NextApiResponse,
|
res: NextApiResponse,
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
!process.env.TWITTER_AUTH_STATE ||
|
!process.env.TWITTER_CLIENT_ID ||
|
||||||
!process.env.TWITTER_AUTH_CODE_CHALLENGE
|
!process.env.TWITTER_AUTH_CALLBACK_URI ||
|
||||||
|
!process.env.TWITTER_AUTH_STATE
|
||||||
) {
|
) {
|
||||||
return res.status(500).send("No state or code_challenge");
|
console.error(new Error(".env is not set"));
|
||||||
|
return res.status(500).json({ error: "Internal server error" });
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -42,7 +44,7 @@ export default withIronSessionApiRoute(async function handler(
|
|||||||
res.status(200).json({ authUrl });
|
res.status(200).json({ authUrl });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
res.status(500).send("Internal server error");
|
res.status(500).json({ error: "Internal server error" });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ironOptions);
|
ironOptions);
|
||||||
@ -50,5 +52,6 @@ ironOptions);
|
|||||||
declare module "iron-session" {
|
declare module "iron-session" {
|
||||||
interface IronSessionData {
|
interface IronSessionData {
|
||||||
code_verifier?: string;
|
code_verifier?: string;
|
||||||
|
refresh_token?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,51 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { TwitterAuthInfoResponse } from "../../types/api-response";
|
import {
|
||||||
|
IcnsVerificationInfoResponse,
|
||||||
|
TwitterAuthInfoResponse,
|
||||||
|
} from "../../types/api-response";
|
||||||
|
import { VerifierMsg } from "../../types/msg";
|
||||||
|
import { request } from "../../utils/url";
|
||||||
|
|
||||||
export default function VerificationPage() {
|
export default function VerificationPage() {
|
||||||
const [twitterAuthInfo, setTwitterAuthInfo] =
|
const [twitterAuthInfo, setTwitterAuthInfo] =
|
||||||
useState<TwitterAuthInfoResponse | null>();
|
useState<TwitterAuthInfoResponse | null>();
|
||||||
|
|
||||||
const fetchAccessToken = async (state: string, code: string) => {
|
|
||||||
const newTwitterAuthInfo: TwitterAuthInfoResponse = await (
|
|
||||||
await fetch(`/api/twitter-auth-info?state=${state}&code=${code}`)
|
|
||||||
).json();
|
|
||||||
|
|
||||||
setTwitterAuthInfo(newTwitterAuthInfo);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const handleVerification = async () => {
|
||||||
const [, state, code] =
|
const [, state, code] =
|
||||||
window.location.search.match(
|
window.location.search.match(
|
||||||
/^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/,
|
/^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/,
|
||||||
) || [];
|
) || [];
|
||||||
|
const newTwitterAuthInfo = await request<TwitterAuthInfoResponse>(
|
||||||
|
`/api/twitter-auth-info?state=${state}&code=${code}`,
|
||||||
|
);
|
||||||
|
|
||||||
fetchAccessToken(state, code);
|
console.log(newTwitterAuthInfo);
|
||||||
|
|
||||||
|
setTwitterAuthInfo(newTwitterAuthInfo);
|
||||||
|
const verifierMsg: VerifierMsg = {
|
||||||
|
name: newTwitterAuthInfo.username,
|
||||||
|
claimer: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
|
||||||
|
contract_address: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
|
||||||
|
chain_id: "osmosis-1",
|
||||||
|
};
|
||||||
|
const icnsVerificationInfo = await request<IcnsVerificationInfoResponse>(
|
||||||
|
"/api/icns-verification",
|
||||||
|
{
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
msg: JSON.stringify(verifierMsg),
|
||||||
|
authToken: newTwitterAuthInfo.accessToken,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
console.log(icnsVerificationInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleVerification();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -7,3 +7,8 @@ export interface TwitterAuthInfoResponse {
|
|||||||
id: string;
|
id: string;
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IcnsVerificationInfoResponse {
|
||||||
|
signature: number[];
|
||||||
|
algorithm: string;
|
||||||
|
}
|
||||||
|
6
types/msg.ts
Normal file
6
types/msg.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface VerifierMsg {
|
||||||
|
name: string;
|
||||||
|
claimer: string;
|
||||||
|
contract_address: string;
|
||||||
|
chain_id: string;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user