Last active
August 9, 2024 02:04
-
-
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 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(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); | |
const info = await agent.getInfo(); | |
const record: PostRecord = { | |
text: "Hello, world! from OAuth client", | |
createdAt: new Date().toISOString(), | |
}; | |
const body: InputSchema = { | |
repo: 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