mirror of
https://github.com/0xPARC/zkmessage.xyz.git
synced 2026-01-08 22:07:58 -05:00
twitter auth flow
This commit is contained in:
@@ -2,6 +2,7 @@ import * as t from "io-ts"
|
||||
|
||||
import { makeHandler, ServerError } from "next-rest/server"
|
||||
import { prisma } from "utils/prisma"
|
||||
import { getTextFromPublicKey, zkChatTwitterHandle } from "utils/verification"
|
||||
|
||||
const postRequestHeaders = t.type({
|
||||
"content-type": t.literal("application/json"),
|
||||
@@ -9,7 +10,6 @@ const postRequestHeaders = t.type({
|
||||
|
||||
const postRequestBody = t.type({
|
||||
publicKey: t.string,
|
||||
twitterHandle: t.string,
|
||||
})
|
||||
|
||||
type PostRequestHeaders = t.TypeOf<typeof postRequestHeaders>
|
||||
@@ -40,6 +40,11 @@ const twitterApiResponse = t.type({
|
||||
oldest_id: t.string,
|
||||
result_count: t.number,
|
||||
}),
|
||||
includes: t.type({
|
||||
users: t.array(
|
||||
t.type({ id: t.string, name: t.string, username: t.string })
|
||||
),
|
||||
}),
|
||||
data: t.array(
|
||||
t.type({
|
||||
id: t.string,
|
||||
@@ -52,11 +57,11 @@ export default makeHandler("/api/users", {
|
||||
POST: {
|
||||
headers: postRequestHeaders.is,
|
||||
body: postRequestBody.is,
|
||||
exec: async ({ body: { publicKey, twitterHandle } }) => {
|
||||
const query = encodeURIComponent(`from:${twitterHandle} "${publicKey}"`)
|
||||
exec: async ({ body: { publicKey } }) => {
|
||||
const query = encodeURIComponent(`@${zkChatTwitterHandle} "${publicKey}"`)
|
||||
|
||||
const res = await fetch(
|
||||
`https://api.twitter.com/2/tweets/search/recent?query=${query}`,
|
||||
`https://api.twitter.com/2/tweets/search/recent?query=${query}&expansions=author_id&user.fields=username`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
|
||||
@@ -79,13 +84,19 @@ export default makeHandler("/api/users", {
|
||||
|
||||
const [{ id, text }] = data.data
|
||||
|
||||
// Change this if we wrap the public key with some text or anything
|
||||
if (text !== publicKey) {
|
||||
if (text !== getTextFromPublicKey(publicKey)) {
|
||||
throw new ServerError(500, "Invalid tweet syntax")
|
||||
}
|
||||
|
||||
const { username } = data.includes.users.find((user) => user.id === id)!
|
||||
|
||||
await prisma.user.create({
|
||||
data: { publicKey, twitterHandle, verificationTweetId: id },
|
||||
data: {
|
||||
publicKey,
|
||||
twitterId: id,
|
||||
twitterHandle: username,
|
||||
verificationTweetId: id,
|
||||
},
|
||||
})
|
||||
|
||||
return { headers: {}, body: undefined }
|
||||
|
||||
@@ -35,7 +35,10 @@ export default function BackupPage(props: {}) {
|
||||
<div className="max-w-lg m-auto font-mono">
|
||||
<Header />
|
||||
<div className="border border-gray-300 rounded-xl p-6">
|
||||
<div>This is your ZK CHAT login token. Keep it secret and save it somewhere safe:</div>
|
||||
<div>
|
||||
This is your ZK CHAT login token. Keep it secret and save it somewhere
|
||||
safe:
|
||||
</div>
|
||||
<textarea
|
||||
className="block w-full outline-none py-5 px-6 my-6 rounded-xl border focus:border-blue-300 resize-none text-gray-800"
|
||||
rows={3}
|
||||
|
||||
@@ -32,8 +32,8 @@ export default function LoginPage(props: {}) {
|
||||
<div className="border border-gray-300 rounded-xl p-6">
|
||||
<div className="text-left mb-4">Log in with a secret token:</div>
|
||||
<textarea
|
||||
className="w-full resize-none px-4 py-3 rounded-xl outline-none border focus:border-blue-300 outline-none"
|
||||
rows="3"
|
||||
className="w-full resize-none px-4 py-3 rounded-xl outline-none border border-transparent"
|
||||
rows={3}
|
||||
placeholder="Your secret token"
|
||||
value={value}
|
||||
onChange={(event) => setValue(event.target.value)}
|
||||
|
||||
@@ -12,6 +12,7 @@ datasource db {
|
||||
|
||||
model User {
|
||||
publicKey String @id
|
||||
twitterId String @unique
|
||||
twitterHandle String @unique
|
||||
verificationTweetId String @unique
|
||||
messages Message[]
|
||||
@@ -20,6 +21,6 @@ model User {
|
||||
model Message {
|
||||
id String @id @default(uuid())
|
||||
authors User[]
|
||||
body String
|
||||
content String
|
||||
proof Bytes
|
||||
}
|
||||
|
||||
5
utils/verification.ts
Normal file
5
utils/verification.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const zkChatTwitterHandle = "zk_chat"
|
||||
|
||||
export function getTextFromPublicKey(publicKey: string) {
|
||||
return `@zk_chat ${publicKey}`
|
||||
}
|
||||
Reference in New Issue
Block a user