Bluesky app fork with some witchin' additions 馃挮
at main 17 kB view raw
1import {createServer as createHTTPServer} from 'node:http' 2import {parse} from 'node:url' 3 4import {createServer, type TestPDS} from '../jest/test-pds' 5 6async function main() { 7 let server: TestPDS 8 createHTTPServer(async (req, res) => { 9 const url = parse(req.url || '/', true) 10 if (req.method !== 'POST') { 11 return res.writeHead(200).end() 12 } 13 try { 14 console.log('Closing old server') 15 await server?.close() 16 console.log('Starting new server') 17 const inviteRequired = url?.query && 'invite' in url.query 18 server = await createServer({inviteRequired}) 19 console.log('Listening at', server.pdsUrl) 20 if (url?.query) { 21 if ('users' in url.query) { 22 console.log('Generating mock users') 23 await server.mocker.createUser('alice') 24 await server.mocker.createUser('bob') 25 await server.mocker.createUser('carla') 26 await server.mocker.users.alice.agent.upsertProfile(() => ({ 27 displayName: 'Alice', 28 description: 'Test user 1', 29 })) 30 await server.mocker.users.bob.agent.upsertProfile(() => ({ 31 displayName: 'Bob', 32 description: 'Test user 2', 33 })) 34 await server.mocker.users.carla.agent.upsertProfile(() => ({ 35 displayName: 'Carla', 36 description: 'Test user 3', 37 })) 38 if (inviteRequired) { 39 await server.mocker.createInvite(server.mocker.users.alice.did) 40 } 41 } 42 if ('follows' in url.query) { 43 console.log('Generating mock follows') 44 await server.mocker.follow('alice', 'bob') 45 await server.mocker.follow('alice', 'carla') 46 await server.mocker.follow('bob', 'alice') 47 await server.mocker.follow('bob', 'carla') 48 await server.mocker.follow('carla', 'alice') 49 await server.mocker.follow('carla', 'bob') 50 } 51 if ('posts' in url.query) { 52 console.log('Generating mock posts') 53 for (let user in server.mocker.users) { 54 await server.mocker.users[user].agent.post({text: 'Post'}) 55 } 56 } 57 if ('feeds' in url.query) { 58 console.log('Generating mock feed') 59 await server.mocker.createFeed('alice', 'alice-favs', []) 60 } 61 if ('thread' in url.query) { 62 console.log('Generating mock posts') 63 const res = await server.mocker.users.bob.agent.post({ 64 text: 'Thread root', 65 }) 66 await server.mocker.users.carla.agent.post({ 67 text: 'Thread reply', 68 reply: { 69 parent: {cid: res.cid, uri: res.uri}, 70 root: {cid: res.cid, uri: res.uri}, 71 }, 72 }) 73 } 74 if ('mergefeed' in url.query) { 75 console.log('Generating mock users') 76 await server.mocker.createUser('alice') 77 await server.mocker.createUser('bob') 78 await server.mocker.createUser('carla') 79 await server.mocker.createUser('dan') 80 await server.mocker.users.alice.agent.upsertProfile(() => ({ 81 displayName: 'Alice', 82 description: 'Test user 1', 83 })) 84 await server.mocker.users.bob.agent.upsertProfile(() => ({ 85 displayName: 'Bob', 86 description: 'Test user 2', 87 })) 88 await server.mocker.users.carla.agent.upsertProfile(() => ({ 89 displayName: 'Carla', 90 description: 'Test user 3', 91 })) 92 await server.mocker.users.dan.agent.upsertProfile(() => ({ 93 displayName: 'Dan', 94 description: 'Test user 4', 95 })) 96 console.log('Generating mock follows') 97 await server.mocker.follow('alice', 'bob') 98 await server.mocker.follow('alice', 'carla') 99 console.log('Generating mock posts') 100 let posts: Record<string, any[]> = { 101 alice: [], 102 bob: [], 103 carla: [], 104 dan: [], 105 } 106 for (let i = 0; i < 10; i++) { 107 for (let user in server.mocker.users) { 108 if (user === 'alice') continue 109 posts[user].push( 110 await server.mocker.createPost(user, `Post ${i}`), 111 ) 112 } 113 } 114 for (let i = 0; i < 10; i++) { 115 for (let user in server.mocker.users) { 116 if (user === 'alice') continue 117 if (i % 5 === 0) { 118 await server.mocker.createReply(user, 'Self reply', { 119 cid: posts[user][i].cid, 120 uri: posts[user][i].uri, 121 }) 122 } 123 if (i % 5 === 1) { 124 await server.mocker.createReply(user, 'Reply to bob', { 125 cid: posts.bob[i].cid, 126 uri: posts.bob[i].uri, 127 }) 128 } 129 if (i % 5 === 2) { 130 await server.mocker.createReply(user, 'Reply to dan', { 131 cid: posts.dan[i].cid, 132 uri: posts.dan[i].uri, 133 }) 134 } 135 await server.mocker.users[user].agent.post({text: `Post ${i}`}) 136 } 137 } 138 console.log('Generating mock feeds') 139 await server.mocker.createFeed( 140 'alice', 141 'alice-favs', 142 posts.dan.map(p => p.uri), 143 ) 144 await server.mocker.createFeed( 145 'alice', 146 'alice-favs2', 147 posts.dan.map(p => p.uri), 148 ) 149 } 150 if ('labels' in url.query) { 151 console.log('Generating naughty users with labels') 152 153 const anchorPost = await server.mocker.createPost( 154 'alice', 155 'Anchor post', 156 ) 157 158 for (const user of [ 159 'dmca-account', 160 'dmca-profile', 161 'dmca-posts', 162 'porn-account', 163 'porn-profile', 164 'porn-posts', 165 'nudity-account', 166 'nudity-profile', 167 'nudity-posts', 168 'scam-account', 169 'scam-profile', 170 'scam-posts', 171 'unknown-account', 172 'unknown-profile', 173 'unknown-posts', 174 'hide-account', 175 'hide-profile', 176 'hide-posts', 177 'no-promote-account', 178 'no-promote-profile', 179 'no-promote-posts', 180 'warn-account', 181 'warn-profile', 182 'warn-posts', 183 'muted-account', 184 'muted-by-list-acc', 185 'blocking-account', 186 'blockedby-account', 187 'mutual-block-acc', 188 ]) { 189 await server.mocker.createUser(user) 190 await server.mocker.follow('alice', user) 191 await server.mocker.follow(user, 'alice') 192 await server.mocker.createPost(user, `Unlabeled post from ${user}`) 193 await server.mocker.createReply( 194 user, 195 `Unlabeled reply from ${user}`, 196 anchorPost, 197 ) 198 await server.mocker.like(user, anchorPost) 199 } 200 201 await server.mocker.labelAccount('dmca-violation', 'dmca-account') 202 await server.mocker.labelProfile('dmca-violation', 'dmca-profile') 203 await server.mocker.labelPost( 204 'dmca-violation', 205 await server.mocker.createPost('dmca-posts', 'dmca post'), 206 ) 207 await server.mocker.labelPost( 208 'dmca-violation', 209 await server.mocker.createQuotePost( 210 'dmca-posts', 211 'dmca quote post', 212 anchorPost, 213 ), 214 ) 215 await server.mocker.labelPost( 216 'dmca-violation', 217 await server.mocker.createReply( 218 'dmca-posts', 219 'dmca reply', 220 anchorPost, 221 ), 222 ) 223 224 await server.mocker.labelAccount('porn', 'porn-account') 225 await server.mocker.labelProfile('porn', 'porn-profile') 226 await server.mocker.labelPost( 227 'porn', 228 await server.mocker.createImagePost('porn-posts', 'porn post'), 229 ) 230 await server.mocker.labelPost( 231 'porn', 232 await server.mocker.createQuotePost( 233 'porn-posts', 234 'porn quote post', 235 anchorPost, 236 ), 237 ) 238 await server.mocker.labelPost( 239 'porn', 240 await server.mocker.createReply( 241 'porn-posts', 242 'porn reply', 243 anchorPost, 244 ), 245 ) 246 247 await server.mocker.labelAccount('nudity', 'nudity-account') 248 await server.mocker.labelProfile('nudity', 'nudity-profile') 249 await server.mocker.labelPost( 250 'nudity', 251 await server.mocker.createImagePost('nudity-posts', 'nudity post'), 252 ) 253 await server.mocker.labelPost( 254 'nudity', 255 await server.mocker.createQuotePost( 256 'nudity-posts', 257 'nudity quote post', 258 anchorPost, 259 ), 260 ) 261 await server.mocker.labelPost( 262 'nudity', 263 await server.mocker.createReply( 264 'nudity-posts', 265 'nudity reply', 266 anchorPost, 267 ), 268 ) 269 270 await server.mocker.labelAccount('scam', 'scam-account') 271 await server.mocker.labelProfile('scam', 'scam-profile') 272 await server.mocker.labelPost( 273 'scam', 274 await server.mocker.createPost('scam-posts', 'scam post'), 275 ) 276 await server.mocker.labelPost( 277 'scam', 278 await server.mocker.createQuotePost( 279 'scam-posts', 280 'scam quote post', 281 anchorPost, 282 ), 283 ) 284 await server.mocker.labelPost( 285 'scam', 286 await server.mocker.createReply( 287 'scam-posts', 288 'scam reply', 289 anchorPost, 290 ), 291 ) 292 293 await server.mocker.labelAccount( 294 'not-a-real-label', 295 'unknown-account', 296 ) 297 await server.mocker.labelProfile( 298 'not-a-real-label', 299 'unknown-profile', 300 ) 301 await server.mocker.labelPost( 302 'not-a-real-label', 303 await server.mocker.createPost('unknown-posts', 'unknown post'), 304 ) 305 await server.mocker.labelPost( 306 'not-a-real-label', 307 await server.mocker.createQuotePost( 308 'unknown-posts', 309 'unknown quote post', 310 anchorPost, 311 ), 312 ) 313 await server.mocker.labelPost( 314 'not-a-real-label', 315 await server.mocker.createReply( 316 'unknown-posts', 317 'unknown reply', 318 anchorPost, 319 ), 320 ) 321 322 await server.mocker.labelAccount('!hide', 'hide-account') 323 await server.mocker.labelProfile('!hide', 'hide-profile') 324 await server.mocker.labelPost( 325 '!hide', 326 await server.mocker.createPost('hide-posts', 'hide post'), 327 ) 328 await server.mocker.labelPost( 329 '!hide', 330 await server.mocker.createQuotePost( 331 'hide-posts', 332 'hide quote post', 333 anchorPost, 334 ), 335 ) 336 await server.mocker.labelPost( 337 '!hide', 338 await server.mocker.createReply( 339 'hide-posts', 340 'hide reply', 341 anchorPost, 342 ), 343 ) 344 345 await server.mocker.labelAccount('!no-promote', 'no-promote-account') 346 await server.mocker.labelProfile('!no-promote', 'no-promote-profile') 347 await server.mocker.labelPost( 348 '!no-promote', 349 await server.mocker.createPost( 350 'no-promote-posts', 351 'no-promote post', 352 ), 353 ) 354 await server.mocker.labelPost( 355 '!no-promote', 356 await server.mocker.createQuotePost( 357 'no-promote-posts', 358 'no-promote quote post', 359 anchorPost, 360 ), 361 ) 362 await server.mocker.labelPost( 363 '!no-promote', 364 await server.mocker.createReply( 365 'no-promote-posts', 366 'no-promote reply', 367 anchorPost, 368 ), 369 ) 370 371 await server.mocker.labelAccount('!warn', 'warn-account') 372 await server.mocker.labelProfile('!warn', 'warn-profile') 373 await server.mocker.labelPost( 374 '!warn', 375 await server.mocker.createPost('warn-posts', 'warn post'), 376 ) 377 await server.mocker.labelPost( 378 '!warn', 379 await server.mocker.createQuotePost( 380 'warn-posts', 381 'warn quote post', 382 anchorPost, 383 ), 384 ) 385 await server.mocker.labelPost( 386 '!warn', 387 await server.mocker.createReply( 388 'warn-posts', 389 'warn reply', 390 anchorPost, 391 ), 392 ) 393 394 await server.mocker.users.alice.agent.mute('muted-account.test') 395 await server.mocker.createPost('muted-account', 'muted post') 396 await server.mocker.createQuotePost( 397 'muted-account', 398 'muted quote post', 399 anchorPost, 400 ) 401 await server.mocker.createReply( 402 'muted-account', 403 'muted reply', 404 anchorPost, 405 ) 406 407 const list = await server.mocker.createMuteList( 408 'alice', 409 'Muted Users', 410 ) 411 await server.mocker.addToMuteList( 412 'alice', 413 list, 414 server.mocker.users['muted-by-list-acc'].did, 415 ) 416 await server.mocker.createPost('muted-by-list-acc', 'muted post') 417 await server.mocker.createQuotePost( 418 'muted-by-list-acc', 419 'account quote post', 420 anchorPost, 421 ) 422 await server.mocker.createReply( 423 'muted-by-list-acc', 424 'account reply', 425 anchorPost, 426 ) 427 428 await server.mocker.createPost('blocking-account', 'blocking post') 429 await server.mocker.createQuotePost( 430 'blocking-account', 431 'blocking quote post', 432 anchorPost, 433 ) 434 await server.mocker.createReply( 435 'blocking-account', 436 'blocking reply', 437 anchorPost, 438 ) 439 await server.mocker.users.alice.agent.app.bsky.graph.block.create( 440 { 441 repo: server.mocker.users.alice.did, 442 }, 443 { 444 subject: server.mocker.users['blocking-account'].did, 445 createdAt: new Date().toISOString(), 446 }, 447 ) 448 449 await server.mocker.createPost('blockedby-account', 'blockedby post') 450 await server.mocker.createQuotePost( 451 'blockedby-account', 452 'blockedby quote post', 453 anchorPost, 454 ) 455 await server.mocker.createReply( 456 'blockedby-account', 457 'blockedby reply', 458 anchorPost, 459 ) 460 await server.mocker.users[ 461 'blockedby-account' 462 ].agent.app.bsky.graph.block.create( 463 { 464 repo: server.mocker.users['blockedby-account'].did, 465 }, 466 { 467 subject: server.mocker.users.alice.did, 468 createdAt: new Date().toISOString(), 469 }, 470 ) 471 472 await server.mocker.createPost( 473 'mutual-block-acc', 474 'mutual-block post', 475 ) 476 await server.mocker.createQuotePost( 477 'mutual-block-acc', 478 'mutual-block quote post', 479 anchorPost, 480 ) 481 await server.mocker.createReply( 482 'mutual-block-acc', 483 'mutual-block reply', 484 anchorPost, 485 ) 486 await server.mocker.users.alice.agent.app.bsky.graph.block.create( 487 { 488 repo: server.mocker.users.alice.did, 489 }, 490 { 491 subject: server.mocker.users['mutual-block-acc'].did, 492 createdAt: new Date().toISOString(), 493 }, 494 ) 495 await server.mocker.users[ 496 'mutual-block-acc' 497 ].agent.app.bsky.graph.block.create( 498 { 499 repo: server.mocker.users['mutual-block-acc'].did, 500 }, 501 { 502 subject: server.mocker.users.alice.did, 503 createdAt: new Date().toISOString(), 504 }, 505 ) 506 507 // flush caches 508 await server.mocker.testNet.processAll() 509 } 510 } 511 console.log('Ready') 512 return res 513 .writeHead(200, { 514 'content-type': 'application/json', 515 }) 516 .end( 517 JSON.stringify({ 518 pdsUrl: server.pdsUrl, 519 appviewDid: server.appviewDid, 520 }), 521 ) 522 } catch (e) { 523 console.error('Error!', e) 524 return res.writeHead(500).end() 525 } 526 }).listen(1986) 527 console.log('Mock server manager listening on 1986') 528} 529main()