this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix label sig formatting in responses

futurGH 09c55f95 bf5fab9b

+30 -12
+5 -4
src/LabelerServer.ts
··· 14 14 import { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 15 15 import type { 16 16 CreateLabelData, 17 - Label, 18 17 ProcedureHandler, 19 18 QueryHandler, 20 19 SavedLabel, 20 + SignedLabel, 21 21 SubscriptionHandler, 22 + UnsignedLabel, 22 23 } from "./util/types.js"; 23 24 import { excludeNullish, frameToBytes } from "./util/util.js"; 24 25 ··· 128 129 * @param label The label to insert. 129 130 * @returns The inserted label. 130 131 */ 131 - private saveLabel(label: Label): SavedLabel { 132 + private saveLabel(label: UnsignedLabel): SavedLabel { 132 133 const signed = labelIsSigned(label) ? label : signLabel(label, this.#signingKey); 133 134 134 135 const stmt = this.db.prepare(` ··· 195 196 * @param seq The label's id. 196 197 * @param label The label to emit. 197 198 */ 198 - private emitLabel(seq: number, label: Label) { 199 + private emitLabel(seq: number, label: SignedLabel) { 199 200 const bytes = frameToBytes("message", { seq, labels: [formatLabel(label)] }, "#labels"); 200 201 this.connections.get("com.atproto.label.subscribeLabels")?.forEach((ws) => { 201 202 ws.send(bytes); ··· 307 308 308 309 const nextCursor = rows[rows.length - 1]?.id?.toString(10) || "0"; 309 310 310 - await res.send({ cursor: nextCursor, labels }); 311 + await res.send({ cursor: nextCursor, labels } satisfies ComAtprotoLabelQueryLabels.Output); 311 312 }; 312 313 313 314 /**
+2
src/index.ts
··· 2 2 export { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 3 3 export type { 4 4 CreateLabelData, 5 + FormattedLabel, 5 6 ProcedureHandler, 6 7 QueryHandler, 7 8 SavedLabel, 8 9 SignedLabel, 9 10 SubscriptionHandler, 11 + UnsignedLabel, 10 12 } from "./util/types.js";
+19 -5
src/util/labels.ts
··· 1 1 import { encode as cborEncode } from "@atcute/cbor"; 2 + import type { At } from "@atcute/client/lexicons"; 3 + import { toString as ui8ToString } from "uint8arrays"; 2 4 import { k256Sign } from "./crypto.js"; 3 - import type { Label, SignedLabel } from "./types.js"; 5 + import type { FormattedLabel, SignedLabel, UnsignedLabel } from "./types.js"; 4 6 import { excludeNullish } from "./util.js"; 5 7 6 8 const LABEL_VERSION = 1; 7 9 8 - export function formatLabel(label: Label): Label { 10 + function formatLabelCbor(label: UnsignedLabel): UnsignedLabel { 9 11 return excludeNullish({ ...label, ver: LABEL_VERSION, neg: !!label.neg }); 10 12 } 11 13 12 - export function signLabel(label: Label, signingKey: Uint8Array): SignedLabel { 13 - const toSign = formatLabel(label); 14 + export function formatLabel( 15 + label: UnsignedLabel & { sig?: Uint8Array | At.Bytes }, 16 + ): FormattedLabel { 17 + const sig = label.sig instanceof Uint8Array 18 + ? { $bytes: ui8ToString(label.sig, "base64") } 19 + : label.sig; 20 + if (sig && !("$bytes" in sig)) { 21 + throw new Error("Expected sig to be an object with base64 $bytes, got " + sig); 22 + } 23 + return excludeNullish({ ...label, ver: LABEL_VERSION, neg: !!label.neg, sig }); 24 + } 25 + 26 + export function signLabel(label: UnsignedLabel, signingKey: Uint8Array): SignedLabel { 27 + const toSign = formatLabelCbor(label); 14 28 const bytes = cborEncode(toSign); 15 29 const sig = k256Sign(signingKey, bytes); 16 30 return { ...toSign, sig }; 17 31 } 18 32 19 - export function labelIsSigned<T extends Label>(label: T): label is T & { sig: Uint8Array } { 33 + export function labelIsSigned<T extends UnsignedLabel>(label: T): label is T & SignedLabel { 20 34 return "sig" in label && label.sig !== undefined; 21 35 }
+4 -3
src/util/types.ts
··· 1 - import type { ComAtprotoLabelDefs } from "@atcute/client/lexicons"; 1 + import { At, ComAtprotoLabelDefs } from "@atcute/client/lexicons"; 2 2 import type { WebsocketHandler } from "@fastify/websocket"; 3 3 import type { 4 4 RawReplyDefaultExpression, ··· 36 36 /** The expiration date of the label, if any. Must be in ISO 8601 format. */ 37 37 exp?: string | undefined; 38 38 } 39 - export type Label = Omit<ComAtprotoLabelDefs.Label, "sig"> & { sig?: Uint8Array }; 40 - export type SignedLabel = Label & { sig: Uint8Array }; 39 + export type UnsignedLabel = Omit<ComAtprotoLabelDefs.Label, "sig">; 40 + export type SignedLabel = UnsignedLabel & { sig: Uint8Array }; 41 + export type FormattedLabel = UnsignedLabel & { sig?: At.Bytes }; 41 42 export type SavedLabel = SignedLabel & { id: number }; 42 43 43 44 export type QueryHandler<