Created
July 23, 2024 16:14
-
-
Save sugyan/be6ba64d1aad3ccf192380b2c0463f8a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createServer, IncomingMessage, ServerResponse } from "http"; | |
import { createHash, randomBytes } from "node:crypto"; | |
import { Key } from "@atproto/jwk"; | |
import { | |
OAuthClient, | |
InternalStateData, | |
Session, | |
DigestAlgorithm, | |
} from "@atproto/oauth-client"; | |
import { AtprotoHandleResolverNode } from "@atproto-labs/handle-resolver-node"; | |
import { JoseKey } from "@atproto/jwk-jose"; | |
import { Awaitable } from "@atproto/oauth-client/dist/util"; | |
import { Record as PostRecord } from "@atproto/api/src/client/types/app/bsky/feed/post"; | |
import { InputSchema } from "@atproto/api/src/client/types/com/atproto/repo/createRecord"; | |
const YOUR_DID = "did:plc:************************"; | |
const PORT = 8888; | |
class MemoryStateStore { | |
private store: Record<string, InternalStateData> = {}; | |
async get(key: string): Promise<undefined | InternalStateData> { | |
return this.store[key]; | |
} | |
async set(key: string, value: InternalStateData): Promise<void> { | |
this.store[key] = value; | |
} | |
async del(key: string): Promise<void> { | |
delete this.store[key]; | |
} | |
} | |
class MemorySessionStore { | |
private store: Record<string, Session> = {}; | |
async get(key: string): Promise<undefined | Session> { | |
return this.store[key]; | |
} | |
async set(key: string, value: Session): Promise<void> { | |
this.store[key] = value; | |
} | |
async del(key: string): Promise<void> { | |
delete this.store[key]; | |
} | |
} | |
(async () => { | |
const client = new OAuthClient({ | |
responseMode: "query", | |
clientMetadata: { | |
client_id: "http://localhost", | |
redirect_uris: [`http://127.0.0.1:${PORT}`], | |
token_endpoint_auth_method: "none", | |
}, | |
stateStore: new MemoryStateStore(), | |
sessionStore: new MemorySessionStore(), | |
handleResolver: new AtprotoHandleResolverNode(), | |
runtimeImplementation: { | |
createKey(algs: string[]): Awaitable<Key> { | |
return JoseKey.generate(algs, "hoge"); | |
}, | |
getRandomValues: randomBytes, | |
digest(data: Uint8Array, alg: DigestAlgorithm): Awaitable<Uint8Array> { | |
return createHash(alg.name).update(data).digest(); | |
}, | |
}, | |
}); | |
const url = await client.authorize(YOUR_DID); | |
console.log(`Open this URL in your browser: ${url}`); | |
createServer(async (req: IncomingMessage, res: ServerResponse) => { | |
if (req.url) { | |
const params = new URLSearchParams(req.url.slice(2)); | |
const { agent } = await client.callback(params); | |
console.log(await agent.getInfo()); | |
const session = await ( | |
await agent.request("/xrpc/com.atproto.server.getSession") | |
).json(); | |
console.log(session); | |
const record: PostRecord = { | |
text: "Hello, world! from OAuth client", | |
createdAt: new Date().toISOString(), | |
}; | |
const body: InputSchema = { | |
repo: session.did, | |
collection: "app.bsky.feed.post", | |
record, | |
}; | |
const output = await ( | |
await agent.request("/xrpc/com.atproto.repo.createRecord", { | |
method: "POST", | |
headers: { "Content-Type": "application/json" }, | |
body: JSON.stringify(body), | |
}) | |
).json(); | |
console.log(output); | |
} | |
res.writeHead(200, { "Content-Type": "text/plain" }); | |
}).listen(PORT); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment