handy online tools for AT Protocol boat.kelinci.net
atproto bluesky atcute typescript solidjs
20
fork

Configure Feed

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

fix: validate plc entries even more

Mary 6c3afaf8 8b0f1e10

+38 -28
+38 -28
src/api/types/plc.ts
··· 19 19 }); 20 20 21 21 const service = v.object({ 22 - type: v.string(), 23 - endpoint: urlString, 22 + type: v.string().assert((input) => input.length <= 256, `service type too long (max 256)`), 23 + endpoint: urlString.assert((input) => input.length <= 512, `service endpoint too long (max 512)`), 24 24 }); 25 25 export type Service = v.Infer<typeof service>; 26 26 ··· 29 29 prev: v.string().nullable(), 30 30 sig: v.string(), 31 31 rotationKeys: v.array(didKeyString).chain((input) => { 32 - if (input.length === 0) { 32 + const len = input.length; 33 + 34 + if (len === 0) { 33 35 return v.err({ message: `missing rotation keys` }); 36 + } else if (len > 10) { 37 + return v.err({ message: `too many rotation keys (max 10)` }); 34 38 } 35 39 36 - for (let i = 0, len = input.length; i < len; i++) { 40 + for (let i = 0; i < len; i++) { 37 41 const key = input[i]; 38 42 39 43 for (let j = 0; j < i; j++) { ··· 49 53 return v.ok(input); 50 54 }), 51 55 verificationMethods: v.record(didKeyString), 52 - alsoKnownAs: v.array(urlString), 53 - services: v.record(service), 56 + alsoKnownAs: v 57 + .array(urlString.assert((input) => input.length <= 256, `alsoKnownAs entry too long (max 256)`)) 58 + .assert((input) => input.length <= 10, `too many alsoKnownAs entries (max 10)`), 59 + services: v 60 + .record(service) 61 + .assert((input) => Object.keys(input).length <= 10, `too many service entries (max 10)`), 54 62 }); 55 63 export type PlcUpdateOp = v.Infer<typeof updateOp>; 56 64 ··· 70 78 export const plcLogEntries = v.array(plcLogEntry); 71 79 72 80 export const updatePayload = updateOp.omit('type', 'prev', 'sig').extend({ 73 - services: v.record( 74 - service.chain((input) => { 75 - switch (input.type) { 76 - case 'AtprotoPersonalDataServer': 77 - case 'AtprotoLabeler': 78 - case 'BskyFeedGenerator': 79 - case 'BskyNotificationService': { 80 - const endpoint = input.endpoint; 81 - const result = serviceUrlString.try(endpoint); 81 + services: v 82 + .record( 83 + service.chain((input) => { 84 + switch (input.type) { 85 + case 'AtprotoPersonalDataServer': 86 + case 'AtprotoLabeler': 87 + case 'BskyFeedGenerator': 88 + case 'BskyNotificationService': { 89 + const endpoint = input.endpoint; 90 + const result = serviceUrlString.try(endpoint); 82 91 83 - if (!result.ok) { 84 - return v.err({ 85 - message: `must be a valid atproto service url`, 86 - path: ['endpoint'], 87 - }); 88 - } 92 + if (!result.ok) { 93 + return v.err({ 94 + message: `must be a valid atproto service url`, 95 + path: ['endpoint'], 96 + }); 97 + } 89 98 90 - const trimmed = endpoint.replace(/\/$/, ''); 99 + const trimmed = endpoint.replace(/\/$/, ''); 91 100 92 - if (endpoint !== trimmed) { 93 - return v.ok({ ...input, endpoint: trimmed }); 101 + if (endpoint !== trimmed) { 102 + return v.ok({ ...input, endpoint: trimmed }); 103 + } 94 104 } 95 105 } 96 - } 97 106 98 - return v.ok(input); 99 - }), 100 - ), 107 + return v.ok(input); 108 + }), 109 + ) 110 + .assert((input) => Object.keys(input).length <= 10, `too many service entries (max 10)`), 101 111 }); 102 112 export type PlcUpdatePayload = v.Infer<typeof updatePayload>;