A discord bot for teal.fm
discord tealfm music
at main 1.9 kB view raw
1import { 2 Keyset, 3 JoseKey, 4 atprotoLoopbackClientMetadata, 5 NodeOAuthClient, 6 type OAuthClientMetadataInput, 7} from "@atproto/oauth-client-node"; 8import { env } from "@tealfmbot/common/constants"; 9import { db } from "@tealfmbot/database/db"; 10import assert from "node:assert"; 11 12import { SessionStore, StateStore } from "./storage.js"; 13 14const loadJwk = async () => { 15 const raw = env.PRIVATE_KEYS; 16 if (!raw) return undefined; 17 const json = JSON.parse(raw); 18 if (!json) return undefined; 19 const keys = await Promise.all( 20 json.map((jwk: string | Record<string, unknown>) => JoseKey.fromJWK(jwk)), 21 ); 22 return new Keyset(keys); 23}; 24 25const keyset = env.PUBLIC_URL && env.PRIVATE_KEYS ? await loadJwk() : undefined; 26 27assert(!env.PUBLIC_URL || keyset?.size, "PRIVATE_KEYS environment variable must be set"); 28 29const pk = keyset?.findPrivateKey({ usage: "sign" }); 30 31const metadata: OAuthClientMetadataInput = env.PUBLIC_URL 32 ? { 33 client_name: "Disco Stu - Teal.fm Discord Bot", 34 client_id: `${env.PUBLIC_URL}/oauth-client-metadata.json`, 35 jwks_uri: `${env.PUBLIC_URL}/.well-known/jwks.json`, 36 redirect_uris: [`${env.PUBLIC_URL}/oauth/callback`], 37 scope: "atproto", 38 grant_types: ["authorization_code", "refresh_token"], 39 response_types: ["code"], 40 application_type: "web", 41 token_endpoint_auth_method: pk ? "private_key_jwt" : "none", 42 token_endpoint_auth_signing_alg: pk ? pk.alg : undefined, 43 dpop_bound_access_tokens: true, 44 } 45 : atprotoLoopbackClientMetadata( 46 `http://localhost?${new URLSearchParams([ 47 ["redirect_uri", `http://127.0.0.1:${env.WEB_SERVICE_PORT}/oauth/callback`], 48 ["scope", "atproto"], 49 ])}`, 50 ); 51 52export const client = new NodeOAuthClient({ 53 ...(typeof keyset !== "undefined" ? { keyset } : undefined), 54 clientMetadata: metadata, 55 stateStore: new StateStore(db), 56 sessionStore: new SessionStore(db), 57});