this repo has no description
0
fork

Configure Feed

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

Fall back to parsing private key as base64 or hex string

futurGH b49371d8 37cf1439

+36 -13
+3 -4
src/LabelerServer.ts
··· 1 1 import "@atcute/ozone/lexicons"; 2 - import { fromBytes } from "@atcute/cbor"; 3 2 import { XRPCError } from "@atcute/client"; 4 3 import type { 5 4 At, ··· 10 9 import fastify, { type FastifyInstance, type FastifyRequest } from "fastify"; 11 10 import Database, { type Database as SQLiteDatabase } from "libsql"; 12 11 import type { WebSocket } from "ws"; 13 - import { verifyJwt } from "./util/crypto.js"; 12 + import { parsePrivateKey, verifyJwt } from "./util/crypto.js"; 14 13 import { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 15 14 import type { 16 15 CreateLabelData, ··· 83 82 84 83 try { 85 84 if (options.signingKey.startsWith("did:key:")) throw 0; 86 - this.#signingKey = fromBytes({ $bytes: options.signingKey }); 85 + this.#signingKey = parsePrivateKey(options.signingKey); 87 86 if (this.#signingKey.byteLength !== 32) throw 0; 88 - } catch (e) { 87 + } catch { 89 88 throw new Error(INVALID_SIGNING_KEY_ERROR); 90 89 } 91 90
+7 -4
src/bin.ts
··· 41 41 }, { 42 42 type: "text", 43 43 name: "privateKey", 44 - message: 45 - "Enter a hex-encoded signing key to use, or leave blank to generate a new one:", 44 + message: "Enter a signing key to use, or leave blank to generate a new one:", 46 45 47 - validate: (value) => 48 - !value || /^[0-9a-f]*$/.test(value) || "Must be a hex-encoded string.", 46 + validate: (value) => { 47 + if (!value) return true; 48 + if (/^[0-9a-f]*$/.test(value)) return true; 49 + if (/^[A-Za-z0-9+/=]+$/.test(value)) return true; 50 + return "Must be a hex or base64-encoded string."; 51 + }, 49 52 }], { onCancel: () => process.exit(1) }); 50 53 51 54 const operation = await plcSetupLabeler({
+5 -5
src/scripts/plc.ts
··· 1 - import { fromBytes, toBytes } from "@atcute/cbor"; 2 1 import type { ComAtprotoIdentitySignPlcOperation } from "@atcute/client/lexicons"; 3 2 import { secp256k1 as k256 } from "@noble/curves/secp256k1"; 4 - import { formatDidKey, SECP256K1_JWT_ALG } from "../util/crypto.js"; 3 + import { toString as ui8ToString } from "uint8arrays/to-string"; 4 + import { formatDidKey, parsePrivateKey, SECP256K1_JWT_ALG } from "../util/crypto.js"; 5 5 import { loginAgent, LoginCredentials } from "./util.js"; 6 6 7 7 /** Options for the {@link plcSetupLabeler} function. */ ··· 16 16 plcToken: string; 17 17 18 18 /** 19 - * You may choose to provide your own hex-encoded secp256k1 signing key to use for the labeler. 19 + * You may choose to provide your own secp256k1 signing key to use for the labeler. 20 20 * Leave this empty to generate a new keypair. 21 21 */ 22 22 privateKey?: string | Uint8Array; ··· 52 52 const privateKey = options.privateKey 53 53 ? options.privateKey instanceof Uint8Array 54 54 ? options.privateKey 55 - : fromBytes({ $bytes: options.privateKey }) 55 + : parsePrivateKey(options.privateKey) 56 56 : k256.utils.randomPrivateKey(); 57 57 58 58 const publicKey = k256.getPublicKey(privateKey); ··· 104 104 }); 105 105 106 106 if (!options.privateKey && operation.verificationMethods) { 107 - const privateKeyString = toBytes(privateKey).$bytes; 107 + const privateKeyString = ui8ToString(privateKey, "hex"); 108 108 console.log( 109 109 "This is your labeler's signing key. It will be needed to sign any labels you create.", 110 110 "You will not be able to retrieve this key again, so make sure to save it somewhere safe.",
+21
src/util/crypto.ts
··· 193 193 }; 194 194 195 195 /** 196 + * Parses a hex- or base64-encoded private key to a Uint8Array. 197 + * @param privateKey The private key to parse. 198 + */ 199 + export const parsePrivateKey = (privateKey: string): Uint8Array => { 200 + let keyBytes: Uint8Array | undefined; 201 + try { 202 + keyBytes = ui8.fromString(privateKey, "hex"); 203 + if (keyBytes.byteLength !== 32) throw 0; 204 + } catch { 205 + try { 206 + keyBytes = ui8.fromString(privateKey, "base64url"); 207 + } catch {} 208 + } finally { 209 + if (!keyBytes) { 210 + throw new Error("Invalid private key. Must be hex or base64url, and 32 bytes long."); 211 + } 212 + return keyBytes; 213 + } 214 + }; 215 + 216 + /** 196 217 * Formats a pubkey in did:key format. 197 218 * @param jwtAlg The JWT algorithm used by the signing key. 198 219 * @param keyBytes The bytes of the pubkey.