decentralised message store
at main 2.6 kB view raw
1import { OWNER_DID, SERVICE_DID } from "@/lib/env"; 2import { getRegistrationState, setRegistrationState } from "@/lib/state"; 3import { prismCommitSchema } from "@/lib/types/prism"; 4import type { RouteHandler, WsRouteHandler } from "@/lib/types/routes"; 5import { newErrorResponse } from "@/lib/utils/http/responses"; 6import { rawDataToString } from "@/lib/utils/ws"; 7import type { RawData } from "ws"; 8import type WebSocket from "ws"; 9 10export const wrapHttpRegistrationCheck = ( 11 routeHandler: RouteHandler, 12): RouteHandler => { 13 const registrationState = getRegistrationState(); 14 const wrappedFunction: RouteHandler = (req, rep) => { 15 if (!registrationState.registered) { 16 return newErrorResponse(503, { 17 message: 18 "Shard has not been registered for use. Register it in the dashboard or make the record yourself using the bootstrapper if you're doing local development.", 19 }); 20 } 21 22 return routeHandler(req, rep); 23 }; 24 25 return wrappedFunction; 26}; 27 28export function wrapWsRegistrationCheck( 29 wsHandler: WsRouteHandler, 30): WsRouteHandler { 31 const registrationState = getRegistrationState(); 32 const wrappedFunction: WsRouteHandler = (socket, request) => { 33 if (!registrationState.registered) { 34 socket.close(1013, "Service unavailable: Shard not yet registered"); 35 return; 36 } 37 38 wsHandler(socket, request); 39 }; 40 41 return wrappedFunction; 42} 43 44export const attachShardRegistrationListener = (socket: WebSocket) => { 45 socket.on("message", (rawData: RawData) => { 46 const data = rawDataToString(rawData); 47 const jsonData: unknown = JSON.parse(data); 48 49 const { success: prismCommitParseSuccess, data: prismCommit } = 50 prismCommitSchema.safeParse(jsonData); 51 if (!prismCommitParseSuccess) return; 52 53 const { did, commit } = prismCommit; 54 if (did !== OWNER_DID) return; 55 56 const { rkey } = commit; 57 58 // TODO: replace empty string with call to resolve did doc and the endpoint and yadda yadda etc. etc. you get it. 59 // if you don't, then the tl;dr is you need to resolve the did:plc document to get the service endpoint describing this lattice and ensure 60 // that the domain/origin/whatever matches with the rkey (or record value if we decide to transition to that) 61 const shardDomain = SERVICE_DID.startsWith("did:web:") 62 ? SERVICE_DID.slice(8) 63 : ""; 64 if (rkey !== shardDomain) return; 65 66 setRegistrationState(true); 67 }); 68};