Merge branch 'main' of github.com:bluesky-social/social-app into main

zio/stable
Paul Frazee 2023-06-28 09:59:16 -05:00
commit 8d32f3de37
5 changed files with 2620 additions and 1387 deletions

View File

@ -34,6 +34,9 @@ async function main() {
displayName: 'Carla', displayName: 'Carla',
description: 'Test user 3', description: 'Test user 3',
})) }))
if (inviteRequired) {
await server.mocker.createInvite(server.mocker.users.alice.did)
}
} }
if ('follows' in url.query) { if ('follows' in url.query) {
console.log('Generating mock follows') console.log('Generating mock follows')

View File

@ -1,20 +1,9 @@
import {AddressInfo} from 'net'
import os from 'os'
import net from 'net' import net from 'net'
import path from 'path' import path from 'path'
import fs from 'fs' import fs from 'fs'
import * as crypto from '@atproto/crypto' import {TestPds as DevEnvTestPDS, TestNetworkNoAppView} from '@atproto/dev-env'
import {PDS, ServerConfig, Database, MemoryBlobStore} from '@atproto/pds'
import * as plc from '@did-plc/lib'
import {PlcServer, Database as PlcDatabase} from '@did-plc/server'
import {BskyAgent} from '@atproto/api' import {BskyAgent} from '@atproto/api'
const ADMIN_PASSWORD = 'admin-pass'
const SECOND = 1000
const MINUTE = SECOND * 60
const HOUR = MINUTE * 60
const DAY = HOUR * 24
export interface TestUser { export interface TestUser {
email: string email: string
did: string did: string
@ -32,81 +21,13 @@ export interface TestPDS {
export async function createServer( export async function createServer(
{inviteRequired}: {inviteRequired: boolean} = {inviteRequired: false}, {inviteRequired}: {inviteRequired: boolean} = {inviteRequired: false},
): Promise<TestPDS> { ): Promise<TestPDS> {
const repoSigningKey = await crypto.Secp256k1Keypair.create()
const plcRotationKey = await crypto.Secp256k1Keypair.create()
const port = await getPort() const port = await getPort()
const port2 = await getPort(port + 1)
const plcDb = PlcDatabase.mock()
const plcServer = PlcServer.create({db: plcDb})
const plcListener = await plcServer.start()
const plcPort = (plcListener.address() as AddressInfo).port
const plcUrl = `http://localhost:${plcPort}`
const recoveryKey = (await crypto.Secp256k1Keypair.create()).did()
const plcClient = new plc.Client(plcUrl)
const serverDid = await plcClient.createDid({
signingKey: repoSigningKey.did(),
rotationKeys: [recoveryKey, plcRotationKey.did()],
handle: 'localhost',
pds: `http://localhost:${port}`,
signer: plcRotationKey,
})
const blobstoreLoc = path.join(os.tmpdir(), crypto.randomStr(5, 'base32'))
const cfg = new ServerConfig({
debugMode: true,
version: '0.0.0',
scheme: 'http',
hostname: 'localhost',
port,
serverDid,
recoveryKey,
adminPassword: ADMIN_PASSWORD,
inviteRequired,
didPlcUrl: plcUrl,
didCacheMaxTTL: DAY,
didCacheStaleTTL: HOUR,
jwtSecret: 'jwt-secret',
availableUserDomains: ['.test'],
appUrlPasswordReset: 'app://forgot-password',
emailNoReplyAddress: 'noreply@blueskyweb.xyz',
publicUrl: `http://localhost:${port}`,
imgUriSalt: '9dd04221f5755bce5f55f47464c27e1e',
imgUriKey:
'f23ecd142835025f42c3db2cf25dd813956c178392760256211f9d315f8ab4d8',
dbPostgresUrl: process.env.DB_POSTGRES_URL,
blobstoreLocation: `${blobstoreLoc}/blobs`,
blobstoreTmp: `${blobstoreLoc}/tmp`,
maxSubscriptionBuffer: 200,
repoBackfillLimitMs: HOUR,
userInviteInterval: 1,
labelerDid: 'did:example:labeler',
labelerKeywords: {},
})
const db =
cfg.dbPostgresUrl !== undefined
? Database.postgres({
url: cfg.dbPostgresUrl,
schema: cfg.dbPostgresSchema,
})
: Database.memory()
await db.migrateToLatestOrThrow()
const blobstore = new MemoryBlobStore()
const pds = PDS.create({
db,
blobstore,
repoSigningKey,
plcRotationKey,
config: cfg,
})
await pds.start()
const pdsUrl = `http://localhost:${port}` const pdsUrl = `http://localhost:${port}`
const {pds, plc} = await TestNetworkNoAppView.create({
pds: {port, publicUrl: pdsUrl, inviteRequired},
plc: {port: port2},
})
const profilePic = fs.readFileSync( const profilePic = fs.readFileSync(
path.join(__dirname, '..', 'assets', 'default-avatar.jpg'), path.join(__dirname, '..', 'assets', 'default-avatar.jpg'),
@ -116,8 +37,8 @@ export async function createServer(
pdsUrl, pdsUrl,
mocker: new Mocker(pds, pdsUrl, profilePic), mocker: new Mocker(pds, pdsUrl, profilePic),
async close() { async close() {
await pds.destroy() await pds.server.destroy()
await plcServer.destroy() await plc.server.destroy()
}, },
} }
} }
@ -127,7 +48,7 @@ class Mocker {
users: Record<string, TestUser> = {} users: Record<string, TestUser> = {}
constructor( constructor(
public pds: PDS, public pds: DevEnvTestPDS,
public service: string, public service: string,
public profilePic: Uint8Array, public profilePic: Uint8Array,
) { ) {
@ -152,7 +73,11 @@ class Mocker {
const inviteRes = await agent.api.com.atproto.server.createInviteCode( const inviteRes = await agent.api.com.atproto.server.createInviteCode(
{useCount: 1}, {useCount: 1},
{ {
headers: {authorization: `Basic ${btoa(`admin:${ADMIN_PASSWORD}`)}`}, headers: {
authorization: `Basic ${btoa(
`admin:${this.pds.ctx.cfg.adminPassword}`,
)}`,
},
encoding: 'application/json', encoding: 'application/json',
}, },
) )
@ -265,6 +190,21 @@ class Mocker {
return await agent.like(uri, cid) return await agent.like(uri, cid)
} }
async createInvite(forAccount: string) {
const agent = new BskyAgent({service: this.agent.service})
await agent.api.com.atproto.server.createInviteCode(
{useCount: 1, forAccount},
{
headers: {
authorization: `Basic ${btoa(
`admin:${this.pds.ctx.cfg.adminPassword}`,
)}`,
},
encoding: 'application/json',
},
)
}
async labelAccount(label: string, user: string) { async labelAccount(label: string, user: string) {
const did = this.users[user]?.did const did = this.users[user]?.did
if (!did) { if (!did) {
@ -380,8 +320,8 @@ const checkAvailablePort = (port: number) =>
}) })
}) })
async function getPort() { async function getPort(start = 3000) {
for (let i = 3000; i < 65000; i++) { for (let i = start; i < 65000; i++) {
if (await checkAvailablePort(i)) { if (await checkAvailablePort(i)) {
return i return i
} }

View File

@ -142,7 +142,8 @@
"zod": "^3.20.2" "zod": "^3.20.2"
}, },
"devDependencies": { "devDependencies": {
"@atproto/pds": "^0.1.10", "@atproto/dev-env": "^0.2.2",
"@atproto/pds": "^0.2.0-beta.2",
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0", "@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0", "@babel/runtime": "^7.20.0",

View File

@ -25,7 +25,8 @@ export const ListActions = ({
let buttons = [ let buttons = [
<Button <Button
key="subscribeButton" key="subscribeListBtn"
testID={muted ? 'unsubscribeListBtn' : 'subscribeListBtn'}
type={muted ? 'inverted' : 'primary'} type={muted ? 'inverted' : 'primary'}
label={muted ? 'Unsubscribe' : 'Subscribe & Mute'} label={muted ? 'Unsubscribe' : 'Subscribe & Mute'}
accessibilityLabel={muted ? 'Unsubscribe' : 'Subscribe and mute'} accessibilityLabel={muted ? 'Unsubscribe' : 'Subscribe and mute'}
@ -34,7 +35,8 @@ export const ListActions = ({
/>, />,
isOwner && ( isOwner && (
<Button <Button
key="editListButton" key="editListBtn"
testID="editListBtn"
type="default" type="default"
label="Edit List" label="Edit List"
accessibilityLabel="Edit list" accessibilityLabel="Edit list"
@ -44,9 +46,9 @@ export const ListActions = ({
), ),
isOwner && ( isOwner && (
<Button <Button
key="deleteListButton" key="deleteListBtn"
type="default"
testID="deleteListBtn" testID="deleteListBtn"
type="default"
accessibilityLabel="Delete list" accessibilityLabel="Delete list"
accessibilityHint="" accessibilityHint=""
onPress={onPressDeleteList}> onPress={onPressDeleteList}>
@ -54,9 +56,9 @@ export const ListActions = ({
</Button> </Button>
), ),
<Button <Button
key="shareListButton" key="shareListBtn"
type="default"
testID="shareListBtn" testID="shareListBtn"
type="default"
accessibilityLabel="Share list" accessibilityLabel="Share list"
accessibilityHint="" accessibilityHint=""
onPress={onPressShareList}> onPress={onPressShareList}>

3865
yarn.lock

File diff suppressed because it is too large Load Diff