Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into eric/app-796-likes-tab
Browse files Browse the repository at this point in the history
* origin:
  Runtime flags in PDS, appview-proxy flags (bluesky-social#1491)
  • Loading branch information
estrattonbailey committed Aug 18, 2023
2 parents 9b1f5f0 + 8de6417 commit 1780afb
Show file tree
Hide file tree
Showing 36 changed files with 173 additions and 33 deletions.
1 change: 1 addition & 0 deletions packages/pds/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"http-terminator": "^3.2.0",
"jsonwebtoken": "^8.5.1",
"kysely": "^0.22.0",
"lru-cache": "^10.0.1",
"multiformats": "^9.6.4",
"nodemailer": "^6.8.0",
"nodemailer-html-to-text": "^3.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/api/com/atproto/identity/resolveHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function (server: Server, ctx: AppContext) {

// this is not someone on our server, but we help with resolving anyway

if (!did && ctx.canProxyRead(req)) {
if (!did && (await ctx.canProxyRead(req))) {
did = await tryResolveFromAppview(ctx.appviewAgent, handle)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/api/com/atproto/repo/getRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function (server: Server, ctx: AppContext) {
}
}

if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req)) {
const res = await ctx.appviewAgent.api.com.atproto.repo.getRecord(params)
return {
encoding: 'application/json',
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/actor/getProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ req, auth, params }) => {
const requester =
auth.credentials.type === 'access' ? auth.credentials.did : null
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.actor.getProfile(
params,
requester
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, auth, params }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.actor.getProfiles(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.actor.getSuggestions(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, auth, params }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.actor.searchActors(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res =
await ctx.appviewAgent.api.app.bsky.actor.searchActorsTypeahead(
params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, auth, params }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getActorFeeds(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ req, params, auth }) => {
const requester =
auth.credentials.type === 'access' ? auth.credentials.did : null
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getAuthorFeed(
params,
requester
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/feed/getFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did

if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const { data: feed } =
await ctx.appviewAgent.api.app.bsky.feed.getFeedGenerator(
{ feed: params.feed },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getFeedGenerator(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getFeedGenerators(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/feed/getLikes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getLikes(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
try {
const res = await ctx.appviewAgent.api.app.bsky.feed.getPostThread(
params,
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/feed/getPosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getPosts(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getRepostedBy(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/feed/getTimeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function (server: Server, ctx: AppContext) {
throw new InvalidRequestError(`Unsupported algorithm: ${algorithm}`)
}

if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.feed.getTimeline(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/graph/getBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getBlocks(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ req, params, auth }) => {
const requester =
auth.credentials.type === 'access' ? auth.credentials.did : null
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getFollowers(
params,
requester
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/graph/getFollows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function (server: Server, ctx: AppContext) {
handler: async ({ req, params, auth }) => {
const requester =
auth.credentials.type === 'access' ? auth.credentials.did : null
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getFollows(
params,
requester
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/graph/getList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getList(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getListMutes(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/graph/getLists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getLists(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/graph/getMutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, auth, params }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res = await ctx.appviewAgent.api.app.bsky.graph.getMutes(
params,
await ctx.serviceAuthHeaders(requester),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, auth, params }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res =
await ctx.appviewAgent.api.app.bsky.notification.getUnreadCount(
params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const res =
await ctx.appviewAgent.api.app.bsky.notification.listNotifications(
params,
Expand Down
2 changes: 1 addition & 1 deletion packages/pds/src/app-view/api/app/bsky/unspecced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function (server: Server, ctx: AppContext) {
auth: ctx.accessVerifier,
handler: async ({ req, params, auth }) => {
const requester = auth.credentials.did
if (ctx.canProxyRead(req)) {
if (await ctx.canProxyRead(req, requester)) {
const hotClassicUri = Object.keys(ctx.algos).find((uri) =>
uri.endsWith('/hot-classic'),
)
Expand Down
30 changes: 24 additions & 6 deletions packages/pds/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { MountedAlgos } from './feed-gen/types'
import { Crawlers } from './crawlers'
import { LabelCache } from './label-cache'
import { ContentReporter } from './content-reporter'
import { RuntimeFlags } from './runtime-flags'

export class AppContext {
constructor(
Expand All @@ -42,6 +43,7 @@ export class AppContext {
sequencerLeader: SequencerLeader | null
labeler: Labeler
labelCache: LabelCache
runtimeFlags: RuntimeFlags
contentReporter?: ContentReporter
backgroundQueue: BackgroundQueue
appviewAgent?: AtpAgent
Expand Down Expand Up @@ -138,6 +140,10 @@ export class AppContext {
return this.opts.labelCache
}

get runtimeFlags(): RuntimeFlags {
return this.opts.runtimeFlags
}

get contentReporter(): ContentReporter | undefined {
return this.opts.contentReporter
}
Expand Down Expand Up @@ -185,12 +191,24 @@ export class AppContext {
return this.opts.appviewAgent
}

canProxyRead(req: express.Request): boolean {
return (
this.cfg.bskyAppViewProxy &&
this.cfg.bskyAppViewEndpoint !== undefined &&
req.get('x-appview-proxy') !== undefined
)
async canProxyRead(
req: express.Request,
did?: string | null,
): Promise<boolean> {
if (!this.cfg.bskyAppViewProxy || !this.cfg.bskyAppViewEndpoint) {
return false
}
if (req.get('x-appview-proxy') !== undefined) {
return true
}
// e.g. /xrpc/a.b.c.d/ -> a.b.c.d/ -> a.b.c.d
const endpoint = req.path.replace('/xrpc/', '').replaceAll('/', '')
if (!did) {
// when no did assigned, only proxy reads if threshold is at max of 10
const threshold = this.runtimeFlags.appviewProxy.getThreshold(endpoint)
return threshold === 10
}
return await this.runtimeFlags.appviewProxy.shouldProxy(endpoint, did)
}

canProxyFeedConstruction(req: express.Request): boolean {
Expand Down
2 changes: 2 additions & 0 deletions packages/pds/src/db/database-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import * as listMute from './tables/list-mute'
import * as label from './tables/label'
import * as repoSeq from './tables/repo-seq'
import * as appMigration from './tables/app-migration'
import * as runtimeFlag from './tables/runtime-flag'
import * as appView from '../app-view/db'

export type DatabaseSchemaType = appView.DatabaseSchemaType &
runtimeFlag.PartialDB &
appMigration.PartialDB &
userAccount.PartialDB &
userState.PartialDB &
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Kysely } from 'kysely'

export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema
.createTable('runtime_flag')
.addColumn('name', 'varchar', (col) => col.primaryKey())
.addColumn('value', 'varchar', (col) => col.notNull())
.execute()
}

export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('runtime_flag').execute()
}
1 change: 1 addition & 0 deletions packages/pds/src/db/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ export * as _20230801T195109532Z from './20230801T195109532Z-remove-moderation-f
export * as _20230807T035309811Z from './20230807T035309811Z-feed-item-delete-invite-for-user-idx'
export * as _20230808T172813122Z from './20230808T172813122Z-repo-rev'
export * as _20230810T203412859Z from './20230810T203412859Z-action-duration'
export * as _20230818T134357818Z from './20230818T134357818Z-runtime-flags'
8 changes: 8 additions & 0 deletions packages/pds/src/db/tables/runtime-flag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface RuntimeFlag {
name: string
value: string
}

export const tableName = 'runtime_flag'

export type PartialDB = { [tableName]: RuntimeFlag }
6 changes: 6 additions & 0 deletions packages/pds/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { Crawlers } from './crawlers'
import { LabelCache } from './label-cache'
import { ContentReporter } from './content-reporter'
import { ModerationService } from './services/moderation'
import { RuntimeFlags } from './runtime-flags'

export type { MountedAlgos } from './feed-gen/types'
export type { ServerConfigValues } from './config'
Expand Down Expand Up @@ -227,6 +228,8 @@ export class PDS {
crawlers,
})

const runtimeFlags = new RuntimeFlags(db)

const ctx = new AppContext({
db,
blobstore,
Expand All @@ -241,6 +244,7 @@ export class PDS {
sequencerLeader,
labeler,
labelCache,
runtimeFlags,
contentReporter,
services,
mailer,
Expand Down Expand Up @@ -309,6 +313,7 @@ export class PDS {
await this.ctx.sequencer.start()
await this.ctx.db.startListeningToChannels()
this.ctx.labelCache.start()
await this.ctx.runtimeFlags.start()
const server = this.app.listen(this.ctx.cfg.port)
this.server = server
this.server.keepAliveTimeout = 90000
Expand All @@ -318,6 +323,7 @@ export class PDS {
}

async destroy(): Promise<void> {
this.ctx.runtimeFlags.destroy()
this.ctx.labelCache.stop()
await this.ctx.sequencerLeader?.destroy()
await this.terminator?.terminate()
Expand Down
Loading

0 comments on commit 1780afb

Please sign in to comment.