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_AUTH_CALLBACK_URI
|
||||
) {
|
||||
return res
|
||||
.status(500)
|
||||
.send(
|
||||
console.error(new Error(".env is not set"));
|
||||
return res.status(500).send({
|
||||
error:
|
||||
"Twitter app client id or client secret or callback URI is not set",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
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 {
|
||||
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;
|
||||
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("code", code as string);
|
||||
params.append("redirect_uri", process.env.TWITTER_AUTH_CALLBACK_URI);
|
||||
params.append("code_verifier", req.session.code_verifier);
|
||||
const { access_token: accessToken } =
|
||||
}
|
||||
|
||||
const { access_token: accessToken, refresh_token } =
|
||||
await request<TwitterOAuth2TokenResponse>(
|
||||
`${twitterApiBaseUrl}/oauth2/token`,
|
||||
{
|
||||
@ -49,6 +59,9 @@ export default withIronSessionApiRoute(async function handler(
|
||||
body: params,
|
||||
},
|
||||
);
|
||||
|
||||
req.session.refresh_token = refresh_token;
|
||||
await req.session.save();
|
||||
const {
|
||||
data: { id, username },
|
||||
} = await request<TwitterUsersMeResponse>(`${twitterApiBaseUrl}/users/me`, {
|
||||
@ -62,8 +75,8 @@ export default withIronSessionApiRoute(async function handler(
|
||||
username,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.status(500).send("Internal server error ");
|
||||
console.error(error);
|
||||
res.status(500).json({ error: "Internal server error " });
|
||||
}
|
||||
},
|
||||
ironOptions);
|
||||
|
@ -14,10 +14,12 @@ export default withIronSessionApiRoute(async function handler(
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (
|
||||
!process.env.TWITTER_AUTH_STATE ||
|
||||
!process.env.TWITTER_AUTH_CODE_CHALLENGE
|
||||
!process.env.TWITTER_CLIENT_ID ||
|
||||
!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 {
|
||||
@ -42,7 +44,7 @@ export default withIronSessionApiRoute(async function handler(
|
||||
res.status(200).json({ authUrl });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send("Internal server error");
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
},
|
||||
ironOptions);
|
||||
@ -50,5 +52,6 @@ ironOptions);
|
||||
declare module "iron-session" {
|
||||
interface IronSessionData {
|
||||
code_verifier?: string;
|
||||
refresh_token?: string;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,51 @@
|
||||
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() {
|
||||
const [twitterAuthInfo, setTwitterAuthInfo] =
|
||||
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(() => {
|
||||
const handleVerification = async () => {
|
||||
const [, state, code] =
|
||||
window.location.search.match(
|
||||
/^(?=.*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 (
|
||||
|
@ -7,3 +7,8 @@ export interface TwitterAuthInfoResponse {
|
||||
id: 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