From 3b000549df2c45995449eb59722c71092736ee39 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 19 Sep 2023 17:31:03 -0500 Subject: [PATCH 01/18] add tags to post lex --- lexicons/app/bsky/feed/defs.json | 7 +++++++ lexicons/app/bsky/feed/post.json | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/lexicons/app/bsky/feed/defs.json b/lexicons/app/bsky/feed/defs.json index 10f2812ce24..22bdd06cd33 100644 --- a/lexicons/app/bsky/feed/defs.json +++ b/lexicons/app/bsky/feed/defs.json @@ -178,6 +178,13 @@ "items": { "type": "ref", "ref": "app.bsky.graph.defs#listViewBasic" } } } + }, + "tag": { + "type": "object", + "required": ["value"], + "properties": { + "value": { "type": "string" } + } } } } diff --git a/lexicons/app/bsky/feed/post.json b/lexicons/app/bsky/feed/post.json index 5622b5cfd50..23278610528 100644 --- a/lexicons/app/bsky/feed/post.json +++ b/lexicons/app/bsky/feed/post.json @@ -38,6 +38,10 @@ "type": "union", "refs": ["com.atproto.label.defs#selfLabels"] }, + "tags": { + "type": "array", + "items": { "type": "ref", "ref": "app.bsky.feed.defs#tag" } + }, "createdAt": { "type": "string", "format": "datetime" } } } From a3d6efc72274b54c7b4621c7bbc5fb083d949545 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 19 Sep 2023 17:53:27 -0500 Subject: [PATCH 02/18] kiss --- lexicons/app/bsky/feed/defs.json | 7 ------- lexicons/app/bsky/feed/post.json | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/lexicons/app/bsky/feed/defs.json b/lexicons/app/bsky/feed/defs.json index 22bdd06cd33..10f2812ce24 100644 --- a/lexicons/app/bsky/feed/defs.json +++ b/lexicons/app/bsky/feed/defs.json @@ -178,13 +178,6 @@ "items": { "type": "ref", "ref": "app.bsky.graph.defs#listViewBasic" } } } - }, - "tag": { - "type": "object", - "required": ["value"], - "properties": { - "value": { "type": "string" } - } } } } diff --git a/lexicons/app/bsky/feed/post.json b/lexicons/app/bsky/feed/post.json index 23278610528..f26841d6705 100644 --- a/lexicons/app/bsky/feed/post.json +++ b/lexicons/app/bsky/feed/post.json @@ -40,7 +40,7 @@ }, "tags": { "type": "array", - "items": { "type": "ref", "ref": "app.bsky.feed.defs#tag" } + "items": { "type": "string" } }, "createdAt": { "type": "string", "format": "datetime" } } From 6c7e5d66b736bf9ad93c16d5c406b955edbda237 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 11:39:57 -0500 Subject: [PATCH 03/18] add richtext facet and validation attrs --- lexicons/app/bsky/richtext/facet.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lexicons/app/bsky/richtext/facet.json b/lexicons/app/bsky/richtext/facet.json index 9addf2f34b7..ea8f2cba288 100644 --- a/lexicons/app/bsky/richtext/facet.json +++ b/lexicons/app/bsky/richtext/facet.json @@ -9,7 +9,7 @@ "index": { "type": "ref", "ref": "#byteSlice" }, "features": { "type": "array", - "items": { "type": "union", "refs": ["#mention", "#link"] } + "items": { "type": "union", "refs": ["#mention", "#link", "#tag"] } } } }, @@ -29,6 +29,14 @@ "uri": { "type": "string", "format": "uri" } } }, + "tag": { + "type": "object", + "description": "A hashtag.", + "required": ["tag"], + "properties": { + "tag": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } + } + }, "byteSlice": { "type": "object", "description": "A text segment. Start is inclusive, end is exclusive. Indices are for utf8-encoded strings.", From 4054b3b456d06640c4d6c0e88a813623b62890e5 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 11:40:42 -0500 Subject: [PATCH 04/18] add tag validation attrs to post --- lexicons/app/bsky/feed/post.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lexicons/app/bsky/feed/post.json b/lexicons/app/bsky/feed/post.json index f26841d6705..01b6831d894 100644 --- a/lexicons/app/bsky/feed/post.json +++ b/lexicons/app/bsky/feed/post.json @@ -40,7 +40,7 @@ }, "tags": { "type": "array", - "items": { "type": "string" } + "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } }, "createdAt": { "type": "string", "format": "datetime" } } From be2f37812f3a36ffa689fecf43321a20bba90b18 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 14:24:54 -0500 Subject: [PATCH 05/18] codegen --- packages/api/src/client/lexicons.ts | 21 +++++++++++++++++++ .../src/client/types/app/bsky/feed/post.ts | 1 + .../client/types/app/bsky/richtext/facet.ts | 18 +++++++++++++++- packages/bsky/src/lexicon/lexicons.ts | 21 +++++++++++++++++++ .../src/lexicon/types/app/bsky/feed/post.ts | 1 + .../lexicon/types/app/bsky/richtext/facet.ts | 18 +++++++++++++++- packages/pds/src/lexicon/lexicons.ts | 21 +++++++++++++++++++ .../src/lexicon/types/app/bsky/feed/post.ts | 1 + .../lexicon/types/app/bsky/richtext/facet.ts | 18 +++++++++++++++- 9 files changed, 117 insertions(+), 3 deletions(-) diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 7ee31c74e62..f4a178cc70d 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -5573,6 +5573,14 @@ export const schemaDict = { type: 'union', refs: ['lex:com.atproto.label.defs#selfLabels'], }, + tags: { + type: 'array', + items: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, createdAt: { type: 'string', format: 'datetime', @@ -6712,6 +6720,7 @@ export const schemaDict = { refs: [ 'lex:app.bsky.richtext.facet#mention', 'lex:app.bsky.richtext.facet#link', + 'lex:app.bsky.richtext.facet#tag', ], }, }, @@ -6739,6 +6748,18 @@ export const schemaDict = { }, }, }, + tag: { + type: 'object', + description: 'A hashtag.', + required: ['tag'], + properties: { + tag: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, + }, byteSlice: { type: 'object', description: diff --git a/packages/api/src/client/types/app/bsky/feed/post.ts b/packages/api/src/client/types/app/bsky/feed/post.ts index 1e326692640..032eef512ec 100644 --- a/packages/api/src/client/types/app/bsky/feed/post.ts +++ b/packages/api/src/client/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + tags?: string[] createdAt: string [k: string]: unknown } diff --git a/packages/api/src/client/types/app/bsky/richtext/facet.ts b/packages/api/src/client/types/app/bsky/richtext/facet.ts index cea86685a0f..96573bb06fe 100644 --- a/packages/api/src/client/types/app/bsky/richtext/facet.ts +++ b/packages/api/src/client/types/app/bsky/richtext/facet.ts @@ -8,7 +8,7 @@ import { CID } from 'multiformats/cid' export interface Main { index: ByteSlice - features: (Mention | Link | { $type: string; [k: string]: unknown })[] + features: (Mention | Link | Tag | { $type: string; [k: string]: unknown })[] [k: string]: unknown } @@ -61,6 +61,22 @@ export function validateLink(v: unknown): ValidationResult { return lexicons.validate('app.bsky.richtext.facet#link', v) } +/** A hashtag. */ +export interface Tag { + tag: string + [k: string]: unknown +} + +export function isTag(v: unknown): v is Tag { + return ( + isObj(v) && hasProp(v, '$type') && v.$type === 'app.bsky.richtext.facet#tag' + ) +} + +export function validateTag(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.richtext.facet#tag', v) +} + /** A text segment. Start is inclusive, end is exclusive. Indices are for utf8-encoded strings. */ export interface ByteSlice { byteStart: number diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 7ee31c74e62..f4a178cc70d 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -5573,6 +5573,14 @@ export const schemaDict = { type: 'union', refs: ['lex:com.atproto.label.defs#selfLabels'], }, + tags: { + type: 'array', + items: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, createdAt: { type: 'string', format: 'datetime', @@ -6712,6 +6720,7 @@ export const schemaDict = { refs: [ 'lex:app.bsky.richtext.facet#mention', 'lex:app.bsky.richtext.facet#link', + 'lex:app.bsky.richtext.facet#tag', ], }, }, @@ -6739,6 +6748,18 @@ export const schemaDict = { }, }, }, + tag: { + type: 'object', + description: 'A hashtag.', + required: ['tag'], + properties: { + tag: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, + }, byteSlice: { type: 'object', description: diff --git a/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts b/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts index 8942bc724cd..3b26d78fac9 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + tags?: string[] createdAt: string [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/types/app/bsky/richtext/facet.ts b/packages/bsky/src/lexicon/types/app/bsky/richtext/facet.ts index a7369ee8d57..2c5b2d723a9 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/richtext/facet.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/richtext/facet.ts @@ -8,7 +8,7 @@ import { CID } from 'multiformats/cid' export interface Main { index: ByteSlice - features: (Mention | Link | { $type: string; [k: string]: unknown })[] + features: (Mention | Link | Tag | { $type: string; [k: string]: unknown })[] [k: string]: unknown } @@ -61,6 +61,22 @@ export function validateLink(v: unknown): ValidationResult { return lexicons.validate('app.bsky.richtext.facet#link', v) } +/** A hashtag. */ +export interface Tag { + tag: string + [k: string]: unknown +} + +export function isTag(v: unknown): v is Tag { + return ( + isObj(v) && hasProp(v, '$type') && v.$type === 'app.bsky.richtext.facet#tag' + ) +} + +export function validateTag(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.richtext.facet#tag', v) +} + /** A text segment. Start is inclusive, end is exclusive. Indices are for utf8-encoded strings. */ export interface ByteSlice { byteStart: number diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 7ee31c74e62..f4a178cc70d 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -5573,6 +5573,14 @@ export const schemaDict = { type: 'union', refs: ['lex:com.atproto.label.defs#selfLabels'], }, + tags: { + type: 'array', + items: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, createdAt: { type: 'string', format: 'datetime', @@ -6712,6 +6720,7 @@ export const schemaDict = { refs: [ 'lex:app.bsky.richtext.facet#mention', 'lex:app.bsky.richtext.facet#link', + 'lex:app.bsky.richtext.facet#tag', ], }, }, @@ -6739,6 +6748,18 @@ export const schemaDict = { }, }, }, + tag: { + type: 'object', + description: 'A hashtag.', + required: ['tag'], + properties: { + tag: { + type: 'string', + maxLength: 640, + maxGraphemes: 64, + }, + }, + }, byteSlice: { type: 'object', description: diff --git a/packages/pds/src/lexicon/types/app/bsky/feed/post.ts b/packages/pds/src/lexicon/types/app/bsky/feed/post.ts index 8942bc724cd..3b26d78fac9 100644 --- a/packages/pds/src/lexicon/types/app/bsky/feed/post.ts +++ b/packages/pds/src/lexicon/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + tags?: string[] createdAt: string [k: string]: unknown } diff --git a/packages/pds/src/lexicon/types/app/bsky/richtext/facet.ts b/packages/pds/src/lexicon/types/app/bsky/richtext/facet.ts index a7369ee8d57..2c5b2d723a9 100644 --- a/packages/pds/src/lexicon/types/app/bsky/richtext/facet.ts +++ b/packages/pds/src/lexicon/types/app/bsky/richtext/facet.ts @@ -8,7 +8,7 @@ import { CID } from 'multiformats/cid' export interface Main { index: ByteSlice - features: (Mention | Link | { $type: string; [k: string]: unknown })[] + features: (Mention | Link | Tag | { $type: string; [k: string]: unknown })[] [k: string]: unknown } @@ -61,6 +61,22 @@ export function validateLink(v: unknown): ValidationResult { return lexicons.validate('app.bsky.richtext.facet#link', v) } +/** A hashtag. */ +export interface Tag { + tag: string + [k: string]: unknown +} + +export function isTag(v: unknown): v is Tag { + return ( + isObj(v) && hasProp(v, '$type') && v.$type === 'app.bsky.richtext.facet#tag' + ) +} + +export function validateTag(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.richtext.facet#tag', v) +} + /** A text segment. Start is inclusive, end is exclusive. Indices are for utf8-encoded strings. */ export interface ByteSlice { byteStart: number From 9fcecda9d6c45e9ca77f518f73205952ef3095ce Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 15:25:30 -0500 Subject: [PATCH 06/18] add maxLength for tags, add description --- lexicons/app/bsky/feed/post.json | 4 +++- packages/api/src/client/lexicons.ts | 2 ++ packages/api/src/client/types/app/bsky/feed/post.ts | 1 + packages/bsky/src/lexicon/lexicons.ts | 2 ++ packages/bsky/src/lexicon/types/app/bsky/feed/post.ts | 1 + packages/pds/src/lexicon/lexicons.ts | 2 ++ packages/pds/src/lexicon/types/app/bsky/feed/post.ts | 1 + 7 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lexicons/app/bsky/feed/post.json b/lexicons/app/bsky/feed/post.json index 01b6831d894..b21f01b6050 100644 --- a/lexicons/app/bsky/feed/post.json +++ b/lexicons/app/bsky/feed/post.json @@ -40,7 +40,9 @@ }, "tags": { "type": "array", - "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } + "maxLength": 8, + "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }, + "description": "Additional non-inline tags describing this post." }, "createdAt": { "type": "string", "format": "datetime" } } diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index f4a178cc70d..5697b4123e6 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -5575,11 +5575,13 @@ export const schemaDict = { }, tags: { type: 'array', + maxLength: 8, items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, + description: 'Additional non-inline tags describing this post.', }, createdAt: { type: 'string', diff --git a/packages/api/src/client/types/app/bsky/feed/post.ts b/packages/api/src/client/types/app/bsky/feed/post.ts index 032eef512ec..a3299e19035 100644 --- a/packages/api/src/client/types/app/bsky/feed/post.ts +++ b/packages/api/src/client/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + /** Additional non-inline tags describing this post. */ tags?: string[] createdAt: string [k: string]: unknown diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index f4a178cc70d..5697b4123e6 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -5575,11 +5575,13 @@ export const schemaDict = { }, tags: { type: 'array', + maxLength: 8, items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, + description: 'Additional non-inline tags describing this post.', }, createdAt: { type: 'string', diff --git a/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts b/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts index 3b26d78fac9..93870b4452d 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + /** Additional non-inline tags describing this post. */ tags?: string[] createdAt: string [k: string]: unknown diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index f4a178cc70d..5697b4123e6 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -5575,11 +5575,13 @@ export const schemaDict = { }, tags: { type: 'array', + maxLength: 8, items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, + description: 'Additional non-inline tags describing this post.', }, createdAt: { type: 'string', diff --git a/packages/pds/src/lexicon/types/app/bsky/feed/post.ts b/packages/pds/src/lexicon/types/app/bsky/feed/post.ts index 3b26d78fac9..93870b4452d 100644 --- a/packages/pds/src/lexicon/types/app/bsky/feed/post.ts +++ b/packages/pds/src/lexicon/types/app/bsky/feed/post.ts @@ -29,6 +29,7 @@ export interface Record { labels?: | ComAtprotoLabelDefs.SelfLabels | { $type: string; [k: string]: unknown } + /** Additional non-inline tags describing this post. */ tags?: string[] createdAt: string [k: string]: unknown From 01ab78a3c4ef8c7cba8fea8bb7895e13f676abac Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 16:15:51 -0500 Subject: [PATCH 07/18] validate post tags on write --- .../src/api/com/atproto/repo/createRecord.ts | 14 +++++++++++++ packages/pds/src/handle/index.ts | 2 +- packages/pds/src/repo/prepare.ts | 2 +- packages/pds/src/util/explicit-slurs.ts | 21 +++++++++++++++++++ packages/pds/src/util/validation.ts | 5 +++++ 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 packages/pds/src/util/explicit-slurs.ts create mode 100644 packages/pds/src/util/validation.ts diff --git a/packages/pds/src/api/com/atproto/repo/createRecord.ts b/packages/pds/src/api/com/atproto/repo/createRecord.ts index 26bc5614785..edc8135f701 100644 --- a/packages/pds/src/api/com/atproto/repo/createRecord.ts +++ b/packages/pds/src/api/com/atproto/repo/createRecord.ts @@ -1,5 +1,6 @@ import { CID } from 'multiformats/cid' import { InvalidRequestError, AuthRequiredError } from '@atproto/xrpc-server' +import { AppBskyFeedPost } from '@atproto/api' import { prepareCreate } from '../../../../repo' import { Server } from '../../../../lexicon' import { @@ -12,6 +13,7 @@ import AppContext from '../../../../context' import { ids } from '../../../../lexicon/lexicons' import Database from '../../../../db' import { ConcurrentWriteError } from '../../../../services/repo' +import { isValidHashtag } from '../../../../util/validation' export default function (server: Server, ctx: AppContext) { server.com.atproto.repo.createRecord({ @@ -44,6 +46,18 @@ export default function (server: Server, ctx: AppContext) { 'Unvalidated writes are not yet supported.', ) } + if (AppBskyFeedPost.isRecord(record)) { + if (record.tags) { + for (const tag of record.tags) { + if (!isValidHashtag(tag)) { + throw new InvalidRequestError( + `Invalid hashtag: ${tag}`, + ) + } + } + } + } + const swapCommitCid = swapCommit ? CID.parse(swapCommit) : undefined let write: PreparedCreate diff --git a/packages/pds/src/handle/index.ts b/packages/pds/src/handle/index.ts index deae5409945..4fadecc5ea4 100644 --- a/packages/pds/src/handle/index.ts +++ b/packages/pds/src/handle/index.ts @@ -1,7 +1,7 @@ import * as ident from '@atproto/syntax' import { InvalidRequestError } from '@atproto/xrpc-server' import { reservedSubdomains } from './reserved' -import { hasExplicitSlur } from './explicit-slurs' +import { hasExplicitSlur } from '../util/explicit-slurs' import AppContext from '../context' export const normalizeAndValidateHandle = async (opts: { diff --git a/packages/pds/src/repo/prepare.ts b/packages/pds/src/repo/prepare.ts index 581701f1f01..3bb22914325 100644 --- a/packages/pds/src/repo/prepare.ts +++ b/packages/pds/src/repo/prepare.ts @@ -33,7 +33,7 @@ import { } from '../lexicon/types/app/bsky/feed/post' import { isRecord as isList } from '../lexicon/types/app/bsky/graph/list' import { isRecord as isProfile } from '../lexicon/types/app/bsky/actor/profile' -import { hasExplicitSlur } from '../handle/explicit-slurs' +import { hasExplicitSlur } from '../util/explicit-slurs' import { InvalidRequestError } from '@atproto/xrpc-server' // @TODO do this dynamically off of schemas diff --git a/packages/pds/src/util/explicit-slurs.ts b/packages/pds/src/util/explicit-slurs.ts new file mode 100644 index 00000000000..534091366f6 --- /dev/null +++ b/packages/pds/src/util/explicit-slurs.ts @@ -0,0 +1,21 @@ +// regexes taken from: https://github.com/Blank-Cheque/Slurs +/* eslint-disable no-misleading-character-class */ +const explicitSlurRegexes = [ + /\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][hĤĥȞȟḦḧḢḣḨḩḤḥḪḫH̱ẖĦħⱧⱨꞪɦꞕΗНн][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, + /\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0]{2}[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, + /\b[fḞḟƑƒꞘꞙᵮᶂ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa@4][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{1,2}([ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeiÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ]{1,2}([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, + /\b[kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLlyÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]*\b/, + /\b[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLloÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOoІіa4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{2}(l[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]t|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeaÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ]?|n[ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]|[a4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa]?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, + /[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLloÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOoІіa4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{2}(l[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]t|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ])[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?/, + /\b[tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa4]+[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn]{1,2}([iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]|[yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ])[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, +] + +export const hasExplicitSlur = (handle: string): boolean => { + return explicitSlurRegexes.some( + (reg) => + reg.test(handle) || + reg.test( + handle.replaceAll('.', '').replaceAll('-', '').replaceAll('_', ''), + ), + ) +} diff --git a/packages/pds/src/util/validation.ts b/packages/pds/src/util/validation.ts new file mode 100644 index 00000000000..4d90ddf657b --- /dev/null +++ b/packages/pds/src/util/validation.ts @@ -0,0 +1,5 @@ +import { hasExplicitSlur } from "./explicit-slurs"; + +export function isValidHashtag(tag: string) { + return hasExplicitSlur(tag); +} From d0b4ccf9ebb65cfd1bd1f20ab2a3467e7b9a3844 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 16:32:17 -0500 Subject: [PATCH 08/18] add test --- .../src/api/com/atproto/repo/createRecord.ts | 4 +--- packages/pds/src/util/validation.ts | 4 ++-- packages/pds/tests/views/posts.test.ts | 22 ++++++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/pds/src/api/com/atproto/repo/createRecord.ts b/packages/pds/src/api/com/atproto/repo/createRecord.ts index edc8135f701..00d86bebbde 100644 --- a/packages/pds/src/api/com/atproto/repo/createRecord.ts +++ b/packages/pds/src/api/com/atproto/repo/createRecord.ts @@ -50,9 +50,7 @@ export default function (server: Server, ctx: AppContext) { if (record.tags) { for (const tag of record.tags) { if (!isValidHashtag(tag)) { - throw new InvalidRequestError( - `Invalid hashtag: ${tag}`, - ) + throw new InvalidRequestError(`Invalid hashtag: ${tag}`) } } } diff --git a/packages/pds/src/util/validation.ts b/packages/pds/src/util/validation.ts index 4d90ddf657b..e7397f22353 100644 --- a/packages/pds/src/util/validation.ts +++ b/packages/pds/src/util/validation.ts @@ -1,5 +1,5 @@ -import { hasExplicitSlur } from "./explicit-slurs"; +import { hasExplicitSlur } from './explicit-slurs' export function isValidHashtag(tag: string) { - return hasExplicitSlur(tag); + return !hasExplicitSlur(tag) } diff --git a/packages/pds/tests/views/posts.test.ts b/packages/pds/tests/views/posts.test.ts index f6aa0551b07..53e9123fed1 100644 --- a/packages/pds/tests/views/posts.test.ts +++ b/packages/pds/tests/views/posts.test.ts @@ -1,4 +1,4 @@ -import AtpAgent from '@atproto/api' +import AtpAgent, { AppBskyFeedPost } from '@atproto/api' import { runTestServer, forSnapshot, TestServerInfo } from '../_util' import { SeedClient } from '../seeds/client' import basicSeed from '../seeds/basic' @@ -62,4 +62,24 @@ describe('pds posts views', () => { ].sort() expect(receivedUris).toEqual(expected) }) + + it('allows for creating posts with tags', async () => { + const post: AppBskyFeedPost.Record = { + text: 'hello world', + tags: ['javascript', 'hehe'], + createdAt: new Date().toISOString(), + } + + const { uri } = await agent.api.app.bsky.feed.post.create( + { repo: sc.dids.alice }, + post, + sc.getHeaders(sc.dids.alice), + ) + const { data } = await agent.api.app.bsky.feed.getPosts( + { uris: [uri] }, + { headers: sc.getHeaders(sc.dids.alice) }, + ) + + expect(data.posts.length).toBe(1) + }) }) From 65735f946199543d612236e9a18071d53695e607 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 16:47:23 -0500 Subject: [PATCH 09/18] handle tags in indexer --- .../20230920T213858047Z-add-tags-to-post.ts | 9 ++++++ packages/bsky/src/db/migrations/index.ts | 1 + packages/bsky/src/db/tables/post.ts | 1 + .../src/services/indexing/plugins/post.ts | 3 ++ packages/bsky/tests/views/posts.test.ts | 28 +++++++++++++++++-- 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 packages/bsky/src/db/migrations/20230920T213858047Z-add-tags-to-post.ts diff --git a/packages/bsky/src/db/migrations/20230920T213858047Z-add-tags-to-post.ts b/packages/bsky/src/db/migrations/20230920T213858047Z-add-tags-to-post.ts new file mode 100644 index 00000000000..9d4e5bd4cfb --- /dev/null +++ b/packages/bsky/src/db/migrations/20230920T213858047Z-add-tags-to-post.ts @@ -0,0 +1,9 @@ +import { Kysely } from 'kysely' + +export async function up(db: Kysely): Promise { + await db.schema.alterTable('post').addColumn('tags', 'jsonb').execute() +} + +export async function down(db: Kysely): Promise { + await db.schema.alterTable('post').dropColumn('tags').execute() +} diff --git a/packages/bsky/src/db/migrations/index.ts b/packages/bsky/src/db/migrations/index.ts index bf18d8dd15b..9e8bfe9cf7f 100644 --- a/packages/bsky/src/db/migrations/index.ts +++ b/packages/bsky/src/db/migrations/index.ts @@ -28,3 +28,4 @@ export * as _20230817T195936007Z from './20230817T195936007Z-native-notification export * as _20230830T205507322Z from './20230830T205507322Z-suggested-feeds' export * as _20230904T211011773Z from './20230904T211011773Z-block-lists' export * as _20230906T222220386Z from './20230906T222220386Z-thread-gating' +export * as _20230920T213858047Z from './20230920T213858047Z-add-tags-to-post' diff --git a/packages/bsky/src/db/tables/post.ts b/packages/bsky/src/db/tables/post.ts index c627efa39e7..6c01b76c8e0 100644 --- a/packages/bsky/src/db/tables/post.ts +++ b/packages/bsky/src/db/tables/post.ts @@ -12,6 +12,7 @@ export interface Post { replyParent: string | null replyParentCid: string | null langs: string[] | null + tags: string[] | null invalidReplyRoot: boolean | null violatesThreadGate: boolean | null createdAt: string diff --git a/packages/bsky/src/services/indexing/plugins/post.ts b/packages/bsky/src/services/indexing/plugins/post.ts index f57bc10179b..40835348f01 100644 --- a/packages/bsky/src/services/indexing/plugins/post.ts +++ b/packages/bsky/src/services/indexing/plugins/post.ts @@ -76,6 +76,9 @@ const insertFn = async ( langs: obj.langs?.length ? sql`${JSON.stringify(obj.langs)}` // sidesteps kysely's array serialization, which is non-jsonb : null, + tags: obj.tags?.length + ? sql`${JSON.stringify(obj.tags)}` // sidesteps kysely's array serialization, which is non-jsonb + : null, indexedAt: timestamp, } const [insertedPost] = await Promise.all([ diff --git a/packages/bsky/tests/views/posts.test.ts b/packages/bsky/tests/views/posts.test.ts index 99ec565dc59..6fa12a085df 100644 --- a/packages/bsky/tests/views/posts.test.ts +++ b/packages/bsky/tests/views/posts.test.ts @@ -1,4 +1,4 @@ -import AtpAgent from '@atproto/api' +import AtpAgent, { AppBskyFeedPost } from '@atproto/api' import { TestNetwork } from '@atproto/dev-env' import { forSnapshot, stripViewerFromPost } from '../_util' import { SeedClient } from '../seeds/client' @@ -7,6 +7,7 @@ import basicSeed from '../seeds/basic' describe('pds posts views', () => { let network: TestNetwork let agent: AtpAgent + let pdsAgent: AtpAgent let sc: SeedClient beforeAll(async () => { @@ -14,7 +15,7 @@ describe('pds posts views', () => { dbPostgresSchema: 'bsky_views_posts', }) agent = network.bsky.getClient() - const pdsAgent = network.pds.getClient() + pdsAgent = network.pds.getClient() sc = new SeedClient(pdsAgent) await basicSeed(sc) await network.processAll() @@ -83,4 +84,27 @@ describe('pds posts views', () => { ].sort() expect(receivedUris).toEqual(expected) }) + + it('allows for creating posts with tags', async () => { + const post: AppBskyFeedPost.Record = { + text: 'hello world', + tags: ['javascript', 'hehe'], + createdAt: new Date().toISOString(), + } + + const { uri } = await pdsAgent.api.app.bsky.feed.post.create( + { repo: sc.dids.alice }, + post, + sc.getHeaders(sc.dids.alice), + ) + + await network.processAll() + await network.bsky.processAll() + + const { data } = await agent.api.app.bsky.feed.getPosts({ uris: [uri] }) + + expect(data.posts.length).toBe(1) + // @ts-ignore we know it's a post record + expect(data.posts[0].record.tags).toEqual(['javascript', 'hehe']) + }) }) From 197da914c939b13279007c07ddff8943f4b13a8c Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 17:00:54 -0500 Subject: [PATCH 10/18] add tags to postView, codegen --- lexicons/app/bsky/feed/defs.json | 6 +- packages/api/docs/labels.md | 54 +- .../api/docs/moderation-behaviors/posts.md | 529 +++++++++++++++++- .../api/docs/moderation-behaviors/profiles.md | 188 ++++++- packages/api/src/client/lexicons.ts | 6 + .../src/client/types/app/bsky/feed/defs.ts | 1 + packages/bsky/src/lexicon/lexicons.ts | 6 + .../src/lexicon/types/app/bsky/feed/defs.ts | 1 + packages/pds/src/lexicon/lexicons.ts | 6 + .../src/lexicon/types/app/bsky/feed/defs.ts | 1 + 10 files changed, 743 insertions(+), 55 deletions(-) diff --git a/lexicons/app/bsky/feed/defs.json b/lexicons/app/bsky/feed/defs.json index 10f2812ce24..7e377a8f1d4 100644 --- a/lexicons/app/bsky/feed/defs.json +++ b/lexicons/app/bsky/feed/defs.json @@ -31,7 +31,11 @@ "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, - "threadgate": { "type": "ref", "ref": "#threadgateView" } + "threadgate": { "type": "ref", "ref": "#threadgateView" }, + "tags": { + "type": "array", + "items": { "type": "string" } + } } }, "viewerState": { diff --git a/packages/api/docs/labels.md b/packages/api/docs/labels.md index a2d8806b566..9531df460c1 100644 --- a/packages/api/docs/labels.md +++ b/packages/api/docs/labels.md @@ -1,44 +1,44 @@ -# Labels + # Labels + + This document is a reference for the labels used in the SDK. -This document is a reference for the labels used in the SDK. + **⚠️ Note**: These labels are still in development and may change over time. Not all are currently in use. -**⚠️ Note**: These labels are still in development and may change over time. Not all are currently in use. + ## Key -## Key + ### Label Preferences -### Label Preferences + The possible client interpretations for a label. -The possible client interpretations for a label. + - ignore Do nothing with the label. + - warn Provide some form of warning on the content (see "On Warn" behavior). + - hide Remove the content from feeds and apply the warning when directly viewed. -- ignore Do nothing with the label. -- warn Provide some form of warning on the content (see "On Warn" behavior). -- hide Remove the content from feeds and apply the warning when directly viewed. + Each label specifies which preferences it can support. If a label is not configurable, it must have only own supported preference. -Each label specifies which preferences it can support. If a label is not configurable, it must have only own supported preference. + ### Configurable? -### Configurable? + Non-configurable labels cannot have their preference changed by the user. -Non-configurable labels cannot have their preference changed by the user. + ### Flags -### Flags + Additional behaviors which a label can adopt. -Additional behaviors which a label can adopt. + - no-override The user cannot click through any covering of content created by the label. + - adult The user must have adult content enabled to configure the label. If adult content is not enabled, the label must adopt the strictest preference. -- no-override The user cannot click through any covering of content created by the label. -- adult The user must have adult content enabled to configure the label. If adult content is not enabled, the label must adopt the strictest preference. + ### On Warn -### On Warn + The kind of UI behavior used when a warning must be applied. -The kind of UI behavior used when a warning must be applied. + - blur Hide all of the content behind an interstitial. + - blur-media Hide only the media within the content (ie images) behind an interstitial. + - alert Display a descriptive warning but do not hide the content. + - null Do nothing. -- blur Hide all of the content behind an interstitial. -- blur-media Hide only the media within the content (ie images) behind an interstitial. -- alert Display a descriptive warning but do not hide the content. -- null Do nothing. - -## Label Behaviors + ## Label Behaviors @@ -267,7 +267,7 @@ The kind of UI behavior used when a warning must be applied.
-## Label Group Descriptions + ## Label Group Descriptions @@ -312,7 +312,7 @@ The kind of UI behavior used when a warning must be applied.
-## Label Descriptions + ## Label Descriptions @@ -535,4 +535,4 @@ The kind of UI behavior used when a warning must be applied. on content
Misleading
The moderators believe this account is spreading misleading information.

-
+ \ No newline at end of file diff --git a/packages/api/docs/moderation-behaviors/posts.md b/packages/api/docs/moderation-behaviors/posts.md index 5ddcf9ff602..ef3c6c7fc5d 100644 --- a/packages/api/docs/moderation-behaviors/posts.md +++ b/packages/api/docs/moderation-behaviors/posts.md @@ -38,12 +38,17 @@ Key: + + + + + Imperative label ('!hide') on author profile @@ -51,6 +56,7 @@ Key: + 🚫 @@ -58,9 +64,13 @@ Key: + + + + Imperative label ('!hide') on author account @@ -76,9 +86,13 @@ Key: + + + + Imperative label ('!hide') on quoted post @@ -86,9 +100,11 @@ Key: + + 🚫 @@ -96,6 +112,9 @@ Key: + + + Imperative label ('!hide') on quoted author account @@ -103,9 +122,11 @@ Key: + + 🚫 @@ -113,6 +134,9 @@ Key: + + + Imperative label ('!no-promote') on post @@ -120,15 +144,21 @@ Key: + + + + + + Imperative label ('!no-promote') on author profile @@ -136,15 +166,21 @@ Key: + + + + + + Imperative label ('!no-promote') on author account @@ -152,15 +188,21 @@ Key: + + + + + + Imperative label ('!no-promote') on quoted post @@ -168,15 +210,21 @@ Key: + + + + + + Imperative label ('!no-promote') on quoted author account @@ -184,15 +232,21 @@ Key: + + + + + + Imperative label ('!warn') on post @@ -204,12 +258,17 @@ Key: + + + + + Imperative label ('!warn') on author profile @@ -217,6 +276,7 @@ Key: + ✋ @@ -224,9 +284,13 @@ Key: + + + + Imperative label ('!warn') on author account @@ -242,9 +306,13 @@ Key: + + + + Imperative label ('!warn') on quoted post @@ -252,9 +320,11 @@ Key: + + ✋ @@ -262,6 +332,9 @@ Key: + + + Imperative label ('!warn') on quoted author account @@ -269,9 +342,11 @@ Key: + + ✋ @@ -279,6 +354,8 @@ Key: + + ScenarioFilterContentAvatarEmbed Blur label ('intolerant') on post (hide) @@ -291,12 +368,17 @@ Key: + + + + + Blur label ('intolerant') on author profile (hide) @@ -304,6 +386,7 @@ Key: + ✋ @@ -311,9 +394,13 @@ Key: + + + + Blur label ('intolerant') on author account (hide) @@ -329,9 +416,13 @@ Key: + + + + Blur label ('intolerant') on quoted post (hide) @@ -339,9 +430,11 @@ Key: + + ✋ @@ -349,6 +442,9 @@ Key: + + + Blur label ('intolerant') on quoted author account (hide) @@ -356,9 +452,11 @@ Key: + + ✋ @@ -366,6 +464,9 @@ Key: + + + Blur label ('intolerant') on post (warn) @@ -377,12 +478,17 @@ Key: + + + + + Blur label ('intolerant') on author profile (warn) @@ -390,6 +496,7 @@ Key: + ✋ @@ -397,9 +504,13 @@ Key: + + + + Blur label ('intolerant') on author account (warn) @@ -415,9 +526,13 @@ Key: + + + + Blur label ('intolerant') on quoted post (warn) @@ -425,9 +540,11 @@ Key: + + ✋ @@ -435,6 +552,9 @@ Key: + + + Blur label ('intolerant') on quoted author account (warn) @@ -442,9 +562,11 @@ Key: + + ✋ @@ -452,6 +574,9 @@ Key: + + + Blur label ('intolerant') on post (ignore) @@ -459,15 +584,21 @@ Key: + + + + + + Blur label ('intolerant') on author profile (ignore) @@ -475,15 +606,21 @@ Key: + + + + + + Blur label ('intolerant') on author account (ignore) @@ -491,15 +628,21 @@ Key: + + + + + + Blur label ('intolerant') on quoted post (ignore) @@ -507,15 +650,21 @@ Key: + + + + + + Blur label ('intolerant') on quoted author account (ignore) @@ -523,15 +672,20 @@ Key: + + + + + ScenarioFilterContentAvatarEmbed Blur-media label ('porn') on post (hide) @@ -540,9 +694,11 @@ Key: + + ✋ @@ -550,6 +706,9 @@ Key: + + + Blur-media label ('porn') on author profile (hide) @@ -557,6 +716,7 @@ Key: + ✋ @@ -564,9 +724,13 @@ Key: + + + + Blur-media label ('porn') on author account (hide) @@ -574,6 +738,7 @@ Key: + ✋ @@ -585,6 +750,9 @@ Key: + + + Blur-media label ('porn') on quoted post (hide) @@ -592,9 +760,11 @@ Key: + + ✋ @@ -602,6 +772,9 @@ Key: + + + Blur-media label ('porn') on quoted author account (hide) @@ -609,15 +782,21 @@ Key: + + + + + + Blur-media label ('porn') on post (warn) @@ -625,9 +804,11 @@ Key: + + ✋ @@ -635,6 +816,9 @@ Key: + + + Blur-media label ('porn') on author profile (warn) @@ -642,6 +826,7 @@ Key: + ✋ @@ -649,9 +834,13 @@ Key: + + + + Blur-media label ('porn') on author account (warn) @@ -659,6 +848,7 @@ Key: + ✋ @@ -670,6 +860,9 @@ Key: + + + Blur-media label ('porn') on quoted post (warn) @@ -677,9 +870,11 @@ Key: + + ✋ @@ -687,6 +882,9 @@ Key: + + + Blur-media label ('porn') on quoted author account (warn) @@ -694,15 +892,21 @@ Key: + + + + + + Blur-media label ('porn') on post (ignore) @@ -710,15 +914,21 @@ Key: + + + + + + Blur-media label ('porn') on author profile (ignore) @@ -726,15 +936,21 @@ Key: + + + + + + Blur-media label ('porn') on author account (ignore) @@ -742,15 +958,21 @@ Key: + + + + + + Blur-media label ('porn') on quoted post (ignore) @@ -758,15 +980,21 @@ Key: + + + + + + Blur-media label ('porn') on quoted author account (ignore) @@ -774,15 +1002,20 @@ Key: + + + + + ScenarioFilterContentAvatarEmbed Notice label ('scam') on post (hide) @@ -792,16 +1025,20 @@ Key: 🪧 - + + + + + Notice label ('scam') on author profile (hide) @@ -809,17 +1046,21 @@ Key: + 🪧 - + + + + Notice label ('scam') on author account (hide) @@ -828,18 +1069,20 @@ Key: 🪧 - 🪧 - + + + + Notice label ('scam') on quoted post (hide) @@ -847,17 +1090,21 @@ Key: + + 🪧 - + + + Notice label ('scam') on quoted author account (hide) @@ -865,17 +1112,21 @@ Key: + + 🪧 - + + + Notice label ('scam') on post (warn) @@ -884,16 +1135,20 @@ Key: 🪧 - + + + + + Notice label ('scam') on author profile (warn) @@ -901,17 +1156,21 @@ Key: + 🪧 - + + + + Notice label ('scam') on author account (warn) @@ -920,18 +1179,20 @@ Key: 🪧 - 🪧 - + + + + Notice label ('scam') on quoted post (warn) @@ -939,17 +1200,21 @@ Key: + + 🪧 - + + + Notice label ('scam') on quoted author account (warn) @@ -957,17 +1222,21 @@ Key: + + 🪧 - + + + Notice label ('scam') on post (ignore) @@ -975,15 +1244,21 @@ Key: + + + + + + Notice label ('scam') on author profile (ignore) @@ -991,15 +1266,21 @@ Key: + + + + + + Notice label ('scam') on author account (ignore) @@ -1007,15 +1288,21 @@ Key: + + + + + + Notice label ('scam') on quoted post (ignore) @@ -1023,15 +1310,21 @@ Key: + + + + + + Notice label ('scam') on quoted author account (ignore) @@ -1039,15 +1332,20 @@ Key: + + + + + ScenarioFilterContentAvatarEmbed Adult-only label on post when adult content is disabled @@ -1056,9 +1354,11 @@ Key: + + 🚫 @@ -1066,6 +1366,9 @@ Key: + + + Adult-only label on author profile when adult content is disabled @@ -1073,6 +1376,7 @@ Key: + 🚫 @@ -1080,9 +1384,13 @@ Key: + + + + Adult-only label on author account when adult content is disabled @@ -1090,6 +1398,7 @@ Key: + 🚫 @@ -1101,6 +1410,9 @@ Key: + + + Adult-only label on quoted post when adult content is disabled @@ -1108,9 +1420,11 @@ Key: + + 🚫 @@ -1118,6 +1432,9 @@ Key: + + + Adult-only label on quoted author account when adult content is disabled @@ -1125,15 +1442,20 @@ Key: + + + + + ScenarioFilterContentAvatarEmbed Self-post: Imperative label ('!hide') on post @@ -1146,12 +1468,17 @@ Key: + + + + + Self-post: Imperative label ('!hide') on author profile @@ -1159,15 +1486,21 @@ Key: + + + + + + Self-post: Imperative label ('!hide') on author account @@ -1175,15 +1508,21 @@ Key: + + + + + + Self-post: Imperative label ('!hide') on quoted post @@ -1191,9 +1530,11 @@ Key: + + ✋ @@ -1201,6 +1542,9 @@ Key: + + + Self-post: Imperative label ('!hide') on quoted author account @@ -1208,15 +1552,21 @@ Key: + + + + + + Self-post: Imperative label ('!warn') on post @@ -1228,12 +1578,17 @@ Key: + + + + + Self-post: Imperative label ('!warn') on author profile @@ -1241,15 +1596,21 @@ Key: + + + + + + Self-post: Imperative label ('!warn') on author account @@ -1257,15 +1618,21 @@ Key: + + + + + + Self-post: Imperative label ('!warn') on quoted post @@ -1273,9 +1640,11 @@ Key: + + ✋ @@ -1283,6 +1652,9 @@ Key: + + + Self-post: Imperative label ('!warn') on quoted author account @@ -1290,15 +1662,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on post (hide) @@ -1306,9 +1684,11 @@ Key: + + ✋ @@ -1316,6 +1696,9 @@ Key: + + + Self-post: Blur-media label ('porn') on author profile (hide) @@ -1323,15 +1706,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on author account (hide) @@ -1339,15 +1728,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on quoted post (hide) @@ -1355,9 +1750,11 @@ Key: + + ✋ @@ -1365,6 +1762,9 @@ Key: + + + Self-post: Blur-media label ('porn') on quoted author account (hide) @@ -1372,15 +1772,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on post (warn) @@ -1388,9 +1794,11 @@ Key: + + ✋ @@ -1398,6 +1806,9 @@ Key: + + + Self-post: Blur-media label ('porn') on author profile (warn) @@ -1405,15 +1816,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on author account (warn) @@ -1421,15 +1838,21 @@ Key: + + + + + + Self-post: Blur-media label ('porn') on quoted post (warn) @@ -1437,9 +1860,11 @@ Key: + + ✋ @@ -1447,6 +1872,9 @@ Key: + + + Self-post: Blur-media label ('porn') on quoted author account (warn) @@ -1454,15 +1882,20 @@ Key: + + + + + ScenarioFilterContentAvatarEmbed Post with blocked author @@ -1479,9 +1912,13 @@ Key: + + + + Post with blocked quoted author @@ -1489,9 +1926,11 @@ Key: + + 🚫 @@ -1499,6 +1938,9 @@ Key: + + + Post with author blocking user @@ -1514,9 +1956,13 @@ Key: + + + + Post with quoted author blocking user @@ -1524,9 +1970,11 @@ Key: + + 🚫 @@ -1534,6 +1982,9 @@ Key: + + + Post with muted author @@ -1545,12 +1996,17 @@ Key: + + + + + Post with muted quoted author @@ -1558,9 +2014,11 @@ Key: + + ✋ @@ -1568,6 +2026,9 @@ Key: + + + Post with muted-by-list author @@ -1579,12 +2040,17 @@ Key: + + + + + Post with muted-by-list quoted author @@ -1592,9 +2058,11 @@ Key: + + ✋ @@ -1602,6 +2070,8 @@ Key: + + ScenarioFilterContentAvatarEmbed Prioritization: post with blocking & blocked-by author @@ -1618,9 +2088,13 @@ Key: + + + + Prioritization: post with blocking & blocked-by quoted author @@ -1628,9 +2102,11 @@ Key: + + 🚫 @@ -1638,6 +2114,9 @@ Key: + + + Prioritization: '!hide' label on post by blocked user @@ -1653,9 +2132,13 @@ Key: + + + + Prioritization: '!hide' label on quoted post, post by blocked user @@ -1675,6 +2158,9 @@ Key: + + + Prioritization: '!hide' and 'intolerant' labels on post (hide) @@ -1686,12 +2172,17 @@ Key: + + + + + Prioritization: '!warn' and 'intolerant' labels on post (hide) @@ -1703,12 +2194,17 @@ Key: + + + + + Prioritization: '!hide' and 'porn' labels on post (hide) @@ -1720,12 +2216,17 @@ Key: + + + + + Prioritization: '!warn' and 'porn' labels on post (hide) @@ -1733,9 +2234,11 @@ Key: + + ✋ @@ -1743,4 +2246,4 @@ Key: - + \ No newline at end of file diff --git a/packages/api/docs/moderation-behaviors/profiles.md b/packages/api/docs/moderation-behaviors/profiles.md index b8d7c94ce91..3d2f9af96b3 100644 --- a/packages/api/docs/moderation-behaviors/profiles.md +++ b/packages/api/docs/moderation-behaviors/profiles.md @@ -38,6 +38,7 @@ Key: + 🚫 @@ -45,6 +46,9 @@ Key: + + + Imperative label ('!hide') on profile @@ -52,6 +56,7 @@ Key: + 🚫 @@ -63,6 +68,9 @@ Key: + + + Imperative label ('!no-promote') on account @@ -70,15 +78,21 @@ Key: + + + + + + Imperative label ('!no-promote') on profile @@ -86,15 +100,21 @@ Key: + + + + + + Imperative label ('!warn') on account @@ -106,6 +126,7 @@ Key: + ✋ @@ -113,6 +134,9 @@ Key: + + + Imperative label ('!warn') on profile @@ -120,6 +144,7 @@ Key: + ✋ @@ -131,6 +156,8 @@ Key: + + ScenarioFilterAccountProfileAvatar Blur label ('intolerant') on account (hide) @@ -143,6 +170,7 @@ Key: + ✋ @@ -150,6 +178,9 @@ Key: + + + Blur label ('intolerant') on profile (hide) @@ -157,6 +188,7 @@ Key: + ✋ @@ -168,6 +200,9 @@ Key: + + + Blur label ('intolerant') on account (warn) @@ -179,6 +214,7 @@ Key: + ✋ @@ -186,6 +222,9 @@ Key: + + + Blur label ('intolerant') on profile (warn) @@ -193,6 +232,7 @@ Key: + ✋ @@ -204,6 +244,9 @@ Key: + + + Blur label ('intolerant') on account (ignore) @@ -211,15 +254,21 @@ Key: + + + + + + Blur label ('intolerant') on profile (ignore) @@ -227,15 +276,20 @@ Key: + + + + + ScenarioFilterAccountProfileAvatar Blur-media label ('porn') on account (hide) @@ -248,6 +302,7 @@ Key: + ✋ @@ -255,6 +310,9 @@ Key: + + + Blur-media label ('porn') on profile (hide) @@ -262,9 +320,11 @@ Key: + + ✋ @@ -272,6 +332,9 @@ Key: + + + Blur-media label ('porn') on account (warn) @@ -283,6 +346,7 @@ Key: + ✋ @@ -290,6 +354,9 @@ Key: + + + Blur-media label ('porn') on profile (warn) @@ -297,9 +364,11 @@ Key: + + ✋ @@ -307,6 +376,9 @@ Key: + + + Blur-media label ('porn') on account (ignore) @@ -314,15 +386,21 @@ Key: + + + + + + Blur-media label ('porn') on profile (ignore) @@ -330,15 +408,20 @@ Key: + + + + + ScenarioFilterAccountProfileAvatar Notice label ('scam') on account (hide) @@ -348,18 +431,20 @@ Key: 🪧 - + 🪧 - + + + Notice label ('scam') on profile (hide) @@ -367,19 +452,21 @@ Key: + 🪧 - 🪧 - + + + Notice label ('scam') on account (warn) @@ -388,18 +475,20 @@ Key: 🪧 - + 🪧 - + + + Notice label ('scam') on profile (warn) @@ -407,19 +496,21 @@ Key: + 🪧 - 🪧 - + + + Notice label ('scam') on account (ignore) @@ -427,15 +518,21 @@ Key: + + + + + + Notice label ('scam') on profile (ignore) @@ -443,15 +540,20 @@ Key: + + + + + ScenarioFilterAccountProfileAvatar Adult-only label on account when adult content is disabled @@ -464,6 +566,7 @@ Key: + 🚫 @@ -471,6 +574,9 @@ Key: + + + Adult-only label on profile when adult content is disabled @@ -478,9 +584,11 @@ Key: + + 🚫 @@ -488,6 +596,8 @@ Key: + + ScenarioFilterAccountProfileAvatar Self-profile: !hide on account @@ -497,18 +607,20 @@ Key: 🪧 - + 🪧 - + + + Self-profile: !hide on profile @@ -516,19 +628,20 @@ Key: + 🪧 - 🪧 - + + ScenarioFilterAccountProfileAvatar Mute/block: Blocking user @@ -537,9 +650,11 @@ Key: + + 🚫 @@ -547,6 +662,9 @@ Key: + + + Mute/block: Blocked by user @@ -554,9 +672,11 @@ Key: + + 🚫 @@ -564,6 +684,9 @@ Key: + + + Mute/block: Muted user @@ -571,15 +694,21 @@ Key: + + + + + + Mute/block: Muted-by-list user @@ -587,15 +716,20 @@ Key: + + + + + ScenarioFilterAccountProfileAvatar Prioritization: blocking & blocked-by user @@ -604,9 +738,11 @@ Key: + + 🚫 @@ -614,6 +750,9 @@ Key: + + + Prioritization: '!hide' label on account of blocked user @@ -625,6 +764,7 @@ Key: + 🚫 @@ -632,6 +772,9 @@ Key: + + + Prioritization: '!hide' and 'intolerant' labels on account (hide) @@ -643,6 +786,7 @@ Key: + 🚫 @@ -650,6 +794,9 @@ Key: + + + Prioritization: '!warn' and 'intolerant' labels on account (hide) @@ -661,6 +808,7 @@ Key: + ✋ @@ -668,6 +816,9 @@ Key: + + + Prioritization: '!warn' and 'porn' labels on account (hide) @@ -679,6 +830,7 @@ Key: + ✋ @@ -686,6 +838,9 @@ Key: + + + Prioritization: intolerant label on account (hide) and scam label on profile (warn) @@ -698,7 +853,6 @@ Key: 🪧 - ✋ @@ -706,6 +860,9 @@ Key: + + + Prioritization: !hide on account, !warn on profile @@ -725,6 +882,9 @@ Key: + + + Prioritization: !warn on account, !hide on profile @@ -744,4 +904,4 @@ Key: - + \ No newline at end of file diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 5697b4123e6..eba24633609 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -4394,6 +4394,12 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, + tags: { + type: 'array', + items: { + type: 'string', + }, + }, }, }, viewerState: { diff --git a/packages/api/src/client/types/app/bsky/feed/defs.ts b/packages/api/src/client/types/app/bsky/feed/defs.ts index 944fd34b072..d11917d2739 100644 --- a/packages/api/src/client/types/app/bsky/feed/defs.ts +++ b/packages/api/src/client/types/app/bsky/feed/defs.ts @@ -32,6 +32,7 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView + tags?: string[] [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 5697b4123e6..eba24633609 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -4394,6 +4394,12 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, + tags: { + type: 'array', + items: { + type: 'string', + }, + }, }, }, viewerState: { diff --git a/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts b/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts index 08d34d88ebb..09a198de442 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts @@ -32,6 +32,7 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView + tags?: string[] [k: string]: unknown } diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 5697b4123e6..eba24633609 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -4394,6 +4394,12 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, + tags: { + type: 'array', + items: { + type: 'string', + }, + }, }, }, viewerState: { diff --git a/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts b/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts index 08d34d88ebb..09a198de442 100644 --- a/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts +++ b/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts @@ -32,6 +32,7 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView + tags?: string[] [k: string]: unknown } From 6036406533e4b6c347d4101f873e4884ef0dd144 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 17:14:29 -0500 Subject: [PATCH 11/18] return tags on post thread view --- packages/bsky/src/services/feed/index.ts | 1 + packages/bsky/src/services/feed/types.ts | 1 + packages/bsky/src/services/feed/views.ts | 1 + packages/bsky/tests/views/thread.test.ts | 31 ++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/bsky/src/services/feed/index.ts b/packages/bsky/src/services/feed/index.ts index f955979e81e..dab9673d9db 100644 --- a/packages/bsky/src/services/feed/index.ts +++ b/packages/bsky/src/services/feed/index.ts @@ -147,6 +147,7 @@ export class FeedService { 'post_agg.likeCount as likeCount', 'post_agg.repostCount as repostCount', 'post_agg.replyCount as replyCount', + 'post.tags as tags', db .selectFrom('repost') .if(!viewer, (q) => q.where(noMatch)) diff --git a/packages/bsky/src/services/feed/types.ts b/packages/bsky/src/services/feed/types.ts index 8d4bd67f6bb..a39cc6d2800 100644 --- a/packages/bsky/src/services/feed/types.ts +++ b/packages/bsky/src/services/feed/types.ts @@ -45,6 +45,7 @@ export type PostInfo = { invalidReplyRoot: boolean violatesThreadGate: boolean viewer: string | null + tags: string[] | null } export type PostInfoMap = { [uri: string]: PostInfo } diff --git a/packages/bsky/src/services/feed/views.ts b/packages/bsky/src/services/feed/views.ts index dc5878db6cd..4c2864b20ed 100644 --- a/packages/bsky/src/services/feed/views.ts +++ b/packages/bsky/src/services/feed/views.ts @@ -214,6 +214,7 @@ export class FeedViews { !post.record.reply && gate ? this.formatThreadgate(gate, lists) : undefined, + tags: post.tags ?? undefined, } } diff --git a/packages/bsky/tests/views/thread.test.ts b/packages/bsky/tests/views/thread.test.ts index d1c96f38603..8ec0b612bde 100644 --- a/packages/bsky/tests/views/thread.test.ts +++ b/packages/bsky/tests/views/thread.test.ts @@ -1,4 +1,4 @@ -import AtpAgent, { AppBskyFeedGetPostThread } from '@atproto/api' +import AtpAgent, { AppBskyFeedGetPostThread, AppBskyFeedPost, AppBskyFeedDefs } from '@atproto/api' import { TestNetwork } from '@atproto/dev-env' import { TAKEDOWN } from '@atproto/api/src/client/types/com/atproto/admin/defs' import { forSnapshot, stripViewerFromThread } from '../_util' @@ -10,6 +10,7 @@ import { isThreadViewPost } from '@atproto/api/src/client/types/app/bsky/feed/de describe('pds thread views', () => { let network: TestNetwork let agent: AtpAgent + let pdsAgent: AtpAgent let sc: SeedClient // account dids, for convenience @@ -22,7 +23,7 @@ describe('pds thread views', () => { dbPostgresSchema: 'bsky_views_thread', }) agent = network.bsky.getClient() - const pdsAgent = network.pds.getClient() + pdsAgent = network.pds.getClient() sc = new SeedClient(pdsAgent) await basicSeed(sc) alice = sc.dids.alice @@ -166,6 +167,32 @@ describe('pds thread views', () => { expect(authorSelfLabels).toEqual(['self-label-a', 'self-label-b']) }) + it('returns tags on the thread view', async () => { + const post: AppBskyFeedPost.Record = { + text: 'hello world', + tags: ['javascript', 'hehe'], + createdAt: new Date().toISOString(), + } + + const { uri } = await pdsAgent.api.app.bsky.feed.post.create( + { repo: sc.dids.alice }, + post, + sc.getHeaders(sc.dids.alice), + ) + + await network.processAll() + await network.bsky.processAll() + + const { data } = await agent.api.app.bsky.feed.getPostThread( + { uri }, + { headers: await network.serviceHeaders(bob) }, + ) + + const thread = data.thread as AppBskyFeedDefs.ThreadViewPost + + expect(thread.post.tags).toEqual(post.tags) + }) + describe('takedown', () => { it('blocks post by actor', async () => { const { data: modAction } = From ce23c30fdb3918b9c69f90de185272f4762aaf0f Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 17:15:12 -0500 Subject: [PATCH 12/18] format --- packages/bsky/tests/views/thread.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bsky/tests/views/thread.test.ts b/packages/bsky/tests/views/thread.test.ts index 8ec0b612bde..6c486acafec 100644 --- a/packages/bsky/tests/views/thread.test.ts +++ b/packages/bsky/tests/views/thread.test.ts @@ -1,4 +1,8 @@ -import AtpAgent, { AppBskyFeedGetPostThread, AppBskyFeedPost, AppBskyFeedDefs } from '@atproto/api' +import AtpAgent, { + AppBskyFeedGetPostThread, + AppBskyFeedPost, + AppBskyFeedDefs, +} from '@atproto/api' import { TestNetwork } from '@atproto/dev-env' import { TAKEDOWN } from '@atproto/api/src/client/types/com/atproto/admin/defs' import { forSnapshot, stripViewerFromThread } from '../_util' From aab6418f2ac99d04994393a8cc3cf79b0b219f60 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Sep 2023 17:16:49 -0500 Subject: [PATCH 13/18] revert formatting change to docs --- packages/api/docs/labels.md | 54 +- .../api/docs/moderation-behaviors/posts.md | 529 +----------------- .../api/docs/moderation-behaviors/profiles.md | 188 +------ 3 files changed, 54 insertions(+), 717 deletions(-) diff --git a/packages/api/docs/labels.md b/packages/api/docs/labels.md index 9531df460c1..a2d8806b566 100644 --- a/packages/api/docs/labels.md +++ b/packages/api/docs/labels.md @@ -1,44 +1,44 @@ - # Labels - - This document is a reference for the labels used in the SDK. +# Labels - **⚠️ Note**: These labels are still in development and may change over time. Not all are currently in use. +This document is a reference for the labels used in the SDK. - ## Key +**⚠️ Note**: These labels are still in development and may change over time. Not all are currently in use. - ### Label Preferences +## Key - The possible client interpretations for a label. +### Label Preferences - - ignore Do nothing with the label. - - warn Provide some form of warning on the content (see "On Warn" behavior). - - hide Remove the content from feeds and apply the warning when directly viewed. +The possible client interpretations for a label. - Each label specifies which preferences it can support. If a label is not configurable, it must have only own supported preference. +- ignore Do nothing with the label. +- warn Provide some form of warning on the content (see "On Warn" behavior). +- hide Remove the content from feeds and apply the warning when directly viewed. - ### Configurable? +Each label specifies which preferences it can support. If a label is not configurable, it must have only own supported preference. - Non-configurable labels cannot have their preference changed by the user. +### Configurable? - ### Flags +Non-configurable labels cannot have their preference changed by the user. - Additional behaviors which a label can adopt. +### Flags - - no-override The user cannot click through any covering of content created by the label. - - adult The user must have adult content enabled to configure the label. If adult content is not enabled, the label must adopt the strictest preference. +Additional behaviors which a label can adopt. - ### On Warn +- no-override The user cannot click through any covering of content created by the label. +- adult The user must have adult content enabled to configure the label. If adult content is not enabled, the label must adopt the strictest preference. - The kind of UI behavior used when a warning must be applied. +### On Warn - - blur Hide all of the content behind an interstitial. - - blur-media Hide only the media within the content (ie images) behind an interstitial. - - alert Display a descriptive warning but do not hide the content. - - null Do nothing. +The kind of UI behavior used when a warning must be applied. - ## Label Behaviors +- blur Hide all of the content behind an interstitial. +- blur-media Hide only the media within the content (ie images) behind an interstitial. +- alert Display a descriptive warning but do not hide the content. +- null Do nothing. + +## Label Behaviors @@ -267,7 +267,7 @@
- ## Label Group Descriptions +## Label Group Descriptions @@ -312,7 +312,7 @@
- ## Label Descriptions +## Label Descriptions @@ -535,4 +535,4 @@ on content
Misleading
The moderators believe this account is spreading misleading information.

-
\ No newline at end of file + diff --git a/packages/api/docs/moderation-behaviors/posts.md b/packages/api/docs/moderation-behaviors/posts.md index ef3c6c7fc5d..5ddcf9ff602 100644 --- a/packages/api/docs/moderation-behaviors/posts.md +++ b/packages/api/docs/moderation-behaviors/posts.md @@ -38,17 +38,12 @@ Key: - - - - - Imperative label ('!hide') on author profile @@ -56,7 +51,6 @@ Key: - 🚫 @@ -64,13 +58,9 @@ Key: - - - - Imperative label ('!hide') on author account @@ -86,13 +76,9 @@ Key: - - - - Imperative label ('!hide') on quoted post @@ -100,11 +86,9 @@ Key: - - 🚫 @@ -112,9 +96,6 @@ Key: - - - Imperative label ('!hide') on quoted author account @@ -122,11 +103,9 @@ Key: - - 🚫 @@ -134,9 +113,6 @@ Key: - - - Imperative label ('!no-promote') on post @@ -144,21 +120,15 @@ Key: - - - - - - Imperative label ('!no-promote') on author profile @@ -166,21 +136,15 @@ Key: - - - - - - Imperative label ('!no-promote') on author account @@ -188,21 +152,15 @@ Key: - - - - - - Imperative label ('!no-promote') on quoted post @@ -210,21 +168,15 @@ Key: - - - - - - Imperative label ('!no-promote') on quoted author account @@ -232,21 +184,15 @@ Key: - - - - - - Imperative label ('!warn') on post @@ -258,17 +204,12 @@ Key: - - - - - Imperative label ('!warn') on author profile @@ -276,7 +217,6 @@ Key: - ✋ @@ -284,13 +224,9 @@ Key: - - - - Imperative label ('!warn') on author account @@ -306,13 +242,9 @@ Key: - - - - Imperative label ('!warn') on quoted post @@ -320,11 +252,9 @@ Key: - - ✋ @@ -332,9 +262,6 @@ Key: - - - Imperative label ('!warn') on quoted author account @@ -342,11 +269,9 @@ Key: - - ✋ @@ -354,8 +279,6 @@ Key: - - ScenarioFilterContentAvatarEmbed Blur label ('intolerant') on post (hide) @@ -368,17 +291,12 @@ Key: - - - - - Blur label ('intolerant') on author profile (hide) @@ -386,7 +304,6 @@ Key: - ✋ @@ -394,13 +311,9 @@ Key: - - - - Blur label ('intolerant') on author account (hide) @@ -416,13 +329,9 @@ Key: - - - - Blur label ('intolerant') on quoted post (hide) @@ -430,11 +339,9 @@ Key: - - ✋ @@ -442,9 +349,6 @@ Key: - - - Blur label ('intolerant') on quoted author account (hide) @@ -452,11 +356,9 @@ Key: - - ✋ @@ -464,9 +366,6 @@ Key: - - - Blur label ('intolerant') on post (warn) @@ -478,17 +377,12 @@ Key: - - - - - Blur label ('intolerant') on author profile (warn) @@ -496,7 +390,6 @@ Key: - ✋ @@ -504,13 +397,9 @@ Key: - - - - Blur label ('intolerant') on author account (warn) @@ -526,13 +415,9 @@ Key: - - - - Blur label ('intolerant') on quoted post (warn) @@ -540,11 +425,9 @@ Key: - - ✋ @@ -552,9 +435,6 @@ Key: - - - Blur label ('intolerant') on quoted author account (warn) @@ -562,11 +442,9 @@ Key: - - ✋ @@ -574,9 +452,6 @@ Key: - - - Blur label ('intolerant') on post (ignore) @@ -584,21 +459,15 @@ Key: - - - - - - Blur label ('intolerant') on author profile (ignore) @@ -606,21 +475,15 @@ Key: - - - - - - Blur label ('intolerant') on author account (ignore) @@ -628,21 +491,15 @@ Key: - - - - - - Blur label ('intolerant') on quoted post (ignore) @@ -650,21 +507,15 @@ Key: - - - - - - Blur label ('intolerant') on quoted author account (ignore) @@ -672,20 +523,15 @@ Key: - - - - - ScenarioFilterContentAvatarEmbed Blur-media label ('porn') on post (hide) @@ -694,11 +540,9 @@ Key: - - ✋ @@ -706,9 +550,6 @@ Key: - - - Blur-media label ('porn') on author profile (hide) @@ -716,7 +557,6 @@ Key: - ✋ @@ -724,13 +564,9 @@ Key: - - - - Blur-media label ('porn') on author account (hide) @@ -738,7 +574,6 @@ Key: - ✋ @@ -750,9 +585,6 @@ Key: - - - Blur-media label ('porn') on quoted post (hide) @@ -760,11 +592,9 @@ Key: - - ✋ @@ -772,9 +602,6 @@ Key: - - - Blur-media label ('porn') on quoted author account (hide) @@ -782,21 +609,15 @@ Key: - - - - - - Blur-media label ('porn') on post (warn) @@ -804,11 +625,9 @@ Key: - - ✋ @@ -816,9 +635,6 @@ Key: - - - Blur-media label ('porn') on author profile (warn) @@ -826,7 +642,6 @@ Key: - ✋ @@ -834,13 +649,9 @@ Key: - - - - Blur-media label ('porn') on author account (warn) @@ -848,7 +659,6 @@ Key: - ✋ @@ -860,9 +670,6 @@ Key: - - - Blur-media label ('porn') on quoted post (warn) @@ -870,11 +677,9 @@ Key: - - ✋ @@ -882,9 +687,6 @@ Key: - - - Blur-media label ('porn') on quoted author account (warn) @@ -892,21 +694,15 @@ Key: - - - - - - Blur-media label ('porn') on post (ignore) @@ -914,21 +710,15 @@ Key: - - - - - - Blur-media label ('porn') on author profile (ignore) @@ -936,21 +726,15 @@ Key: - - - - - - Blur-media label ('porn') on author account (ignore) @@ -958,21 +742,15 @@ Key: - - - - - - Blur-media label ('porn') on quoted post (ignore) @@ -980,21 +758,15 @@ Key: - - - - - - Blur-media label ('porn') on quoted author account (ignore) @@ -1002,20 +774,15 @@ Key: - - - - - ScenarioFilterContentAvatarEmbed Notice label ('scam') on post (hide) @@ -1025,20 +792,16 @@ Key: 🪧 + - - - - - Notice label ('scam') on author profile (hide) @@ -1046,21 +809,17 @@ Key: - 🪧 + - - - - Notice label ('scam') on author account (hide) @@ -1069,20 +828,18 @@ Key: 🪧 + 🪧 + - - - - Notice label ('scam') on quoted post (hide) @@ -1090,21 +847,17 @@ Key: - - 🪧 + - - - Notice label ('scam') on quoted author account (hide) @@ -1112,21 +865,17 @@ Key: - - 🪧 + - - - Notice label ('scam') on post (warn) @@ -1135,20 +884,16 @@ Key: 🪧 + - - - - - Notice label ('scam') on author profile (warn) @@ -1156,21 +901,17 @@ Key: - 🪧 + - - - - Notice label ('scam') on author account (warn) @@ -1179,20 +920,18 @@ Key: 🪧 + 🪧 + - - - - Notice label ('scam') on quoted post (warn) @@ -1200,21 +939,17 @@ Key: - - 🪧 + - - - Notice label ('scam') on quoted author account (warn) @@ -1222,21 +957,17 @@ Key: - - 🪧 + - - - Notice label ('scam') on post (ignore) @@ -1244,21 +975,15 @@ Key: - - - - - - Notice label ('scam') on author profile (ignore) @@ -1266,21 +991,15 @@ Key: - - - - - - Notice label ('scam') on author account (ignore) @@ -1288,21 +1007,15 @@ Key: - - - - - - Notice label ('scam') on quoted post (ignore) @@ -1310,21 +1023,15 @@ Key: - - - - - - Notice label ('scam') on quoted author account (ignore) @@ -1332,20 +1039,15 @@ Key: - - - - - ScenarioFilterContentAvatarEmbed Adult-only label on post when adult content is disabled @@ -1354,11 +1056,9 @@ Key: - - 🚫 @@ -1366,9 +1066,6 @@ Key: - - - Adult-only label on author profile when adult content is disabled @@ -1376,7 +1073,6 @@ Key: - 🚫 @@ -1384,13 +1080,9 @@ Key: - - - - Adult-only label on author account when adult content is disabled @@ -1398,7 +1090,6 @@ Key: - 🚫 @@ -1410,9 +1101,6 @@ Key: - - - Adult-only label on quoted post when adult content is disabled @@ -1420,11 +1108,9 @@ Key: - - 🚫 @@ -1432,9 +1118,6 @@ Key: - - - Adult-only label on quoted author account when adult content is disabled @@ -1442,20 +1125,15 @@ Key: - - - - - ScenarioFilterContentAvatarEmbed Self-post: Imperative label ('!hide') on post @@ -1468,17 +1146,12 @@ Key: - - - - - Self-post: Imperative label ('!hide') on author profile @@ -1486,21 +1159,15 @@ Key: - - - - - - Self-post: Imperative label ('!hide') on author account @@ -1508,21 +1175,15 @@ Key: - - - - - - Self-post: Imperative label ('!hide') on quoted post @@ -1530,11 +1191,9 @@ Key: - - ✋ @@ -1542,9 +1201,6 @@ Key: - - - Self-post: Imperative label ('!hide') on quoted author account @@ -1552,21 +1208,15 @@ Key: - - - - - - Self-post: Imperative label ('!warn') on post @@ -1578,17 +1228,12 @@ Key: - - - - - Self-post: Imperative label ('!warn') on author profile @@ -1596,21 +1241,15 @@ Key: - - - - - - Self-post: Imperative label ('!warn') on author account @@ -1618,21 +1257,15 @@ Key: - - - - - - Self-post: Imperative label ('!warn') on quoted post @@ -1640,11 +1273,9 @@ Key: - - ✋ @@ -1652,9 +1283,6 @@ Key: - - - Self-post: Imperative label ('!warn') on quoted author account @@ -1662,21 +1290,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on post (hide) @@ -1684,11 +1306,9 @@ Key: - - ✋ @@ -1696,9 +1316,6 @@ Key: - - - Self-post: Blur-media label ('porn') on author profile (hide) @@ -1706,21 +1323,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on author account (hide) @@ -1728,21 +1339,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on quoted post (hide) @@ -1750,11 +1355,9 @@ Key: - - ✋ @@ -1762,9 +1365,6 @@ Key: - - - Self-post: Blur-media label ('porn') on quoted author account (hide) @@ -1772,21 +1372,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on post (warn) @@ -1794,11 +1388,9 @@ Key: - - ✋ @@ -1806,9 +1398,6 @@ Key: - - - Self-post: Blur-media label ('porn') on author profile (warn) @@ -1816,21 +1405,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on author account (warn) @@ -1838,21 +1421,15 @@ Key: - - - - - - Self-post: Blur-media label ('porn') on quoted post (warn) @@ -1860,11 +1437,9 @@ Key: - - ✋ @@ -1872,9 +1447,6 @@ Key: - - - Self-post: Blur-media label ('porn') on quoted author account (warn) @@ -1882,20 +1454,15 @@ Key: - - - - - ScenarioFilterContentAvatarEmbed Post with blocked author @@ -1912,13 +1479,9 @@ Key: - - - - Post with blocked quoted author @@ -1926,11 +1489,9 @@ Key: - - 🚫 @@ -1938,9 +1499,6 @@ Key: - - - Post with author blocking user @@ -1956,13 +1514,9 @@ Key: - - - - Post with quoted author blocking user @@ -1970,11 +1524,9 @@ Key: - - 🚫 @@ -1982,9 +1534,6 @@ Key: - - - Post with muted author @@ -1996,17 +1545,12 @@ Key: - - - - - Post with muted quoted author @@ -2014,11 +1558,9 @@ Key: - - ✋ @@ -2026,9 +1568,6 @@ Key: - - - Post with muted-by-list author @@ -2040,17 +1579,12 @@ Key: - - - - - Post with muted-by-list quoted author @@ -2058,11 +1592,9 @@ Key: - - ✋ @@ -2070,8 +1602,6 @@ Key: - - ScenarioFilterContentAvatarEmbed Prioritization: post with blocking & blocked-by author @@ -2088,13 +1618,9 @@ Key: - - - - Prioritization: post with blocking & blocked-by quoted author @@ -2102,11 +1628,9 @@ Key: - - 🚫 @@ -2114,9 +1638,6 @@ Key: - - - Prioritization: '!hide' label on post by blocked user @@ -2132,13 +1653,9 @@ Key: - - - - Prioritization: '!hide' label on quoted post, post by blocked user @@ -2158,9 +1675,6 @@ Key: - - - Prioritization: '!hide' and 'intolerant' labels on post (hide) @@ -2172,17 +1686,12 @@ Key: - - - - - Prioritization: '!warn' and 'intolerant' labels on post (hide) @@ -2194,17 +1703,12 @@ Key: - - - - - Prioritization: '!hide' and 'porn' labels on post (hide) @@ -2216,17 +1720,12 @@ Key: - - - - - Prioritization: '!warn' and 'porn' labels on post (hide) @@ -2234,11 +1733,9 @@ Key: - - ✋ @@ -2246,4 +1743,4 @@ Key: - \ No newline at end of file + diff --git a/packages/api/docs/moderation-behaviors/profiles.md b/packages/api/docs/moderation-behaviors/profiles.md index 3d2f9af96b3..b8d7c94ce91 100644 --- a/packages/api/docs/moderation-behaviors/profiles.md +++ b/packages/api/docs/moderation-behaviors/profiles.md @@ -38,7 +38,6 @@ Key: - 🚫 @@ -46,9 +45,6 @@ Key: - - - Imperative label ('!hide') on profile @@ -56,7 +52,6 @@ Key: - 🚫 @@ -68,9 +63,6 @@ Key: - - - Imperative label ('!no-promote') on account @@ -78,21 +70,15 @@ Key: - - - - - - Imperative label ('!no-promote') on profile @@ -100,21 +86,15 @@ Key: - - - - - - Imperative label ('!warn') on account @@ -126,7 +106,6 @@ Key: - ✋ @@ -134,9 +113,6 @@ Key: - - - Imperative label ('!warn') on profile @@ -144,7 +120,6 @@ Key: - ✋ @@ -156,8 +131,6 @@ Key: - - ScenarioFilterAccountProfileAvatar Blur label ('intolerant') on account (hide) @@ -170,7 +143,6 @@ Key: - ✋ @@ -178,9 +150,6 @@ Key: - - - Blur label ('intolerant') on profile (hide) @@ -188,7 +157,6 @@ Key: - ✋ @@ -200,9 +168,6 @@ Key: - - - Blur label ('intolerant') on account (warn) @@ -214,7 +179,6 @@ Key: - ✋ @@ -222,9 +186,6 @@ Key: - - - Blur label ('intolerant') on profile (warn) @@ -232,7 +193,6 @@ Key: - ✋ @@ -244,9 +204,6 @@ Key: - - - Blur label ('intolerant') on account (ignore) @@ -254,21 +211,15 @@ Key: - - - - - - Blur label ('intolerant') on profile (ignore) @@ -276,20 +227,15 @@ Key: - - - - - ScenarioFilterAccountProfileAvatar Blur-media label ('porn') on account (hide) @@ -302,7 +248,6 @@ Key: - ✋ @@ -310,9 +255,6 @@ Key: - - - Blur-media label ('porn') on profile (hide) @@ -320,11 +262,9 @@ Key: - - ✋ @@ -332,9 +272,6 @@ Key: - - - Blur-media label ('porn') on account (warn) @@ -346,7 +283,6 @@ Key: - ✋ @@ -354,9 +290,6 @@ Key: - - - Blur-media label ('porn') on profile (warn) @@ -364,11 +297,9 @@ Key: - - ✋ @@ -376,9 +307,6 @@ Key: - - - Blur-media label ('porn') on account (ignore) @@ -386,21 +314,15 @@ Key: - - - - - - Blur-media label ('porn') on profile (ignore) @@ -408,20 +330,15 @@ Key: - - - - - ScenarioFilterAccountProfileAvatar Notice label ('scam') on account (hide) @@ -431,20 +348,18 @@ Key: 🪧 + - 🪧 + - - - Notice label ('scam') on profile (hide) @@ -452,21 +367,19 @@ Key: - 🪧 + 🪧 + - - - Notice label ('scam') on account (warn) @@ -475,20 +388,18 @@ Key: 🪧 + - 🪧 + - - - Notice label ('scam') on profile (warn) @@ -496,21 +407,19 @@ Key: - 🪧 + 🪧 + - - - Notice label ('scam') on account (ignore) @@ -518,21 +427,15 @@ Key: - - - - - - Notice label ('scam') on profile (ignore) @@ -540,20 +443,15 @@ Key: - - - - - ScenarioFilterAccountProfileAvatar Adult-only label on account when adult content is disabled @@ -566,7 +464,6 @@ Key: - 🚫 @@ -574,9 +471,6 @@ Key: - - - Adult-only label on profile when adult content is disabled @@ -584,11 +478,9 @@ Key: - - 🚫 @@ -596,8 +488,6 @@ Key: - - ScenarioFilterAccountProfileAvatar Self-profile: !hide on account @@ -607,20 +497,18 @@ Key: 🪧 + - 🪧 + - - - Self-profile: !hide on profile @@ -628,20 +516,19 @@ Key: - 🪧 + 🪧 + - - ScenarioFilterAccountProfileAvatar Mute/block: Blocking user @@ -650,11 +537,9 @@ Key: - - 🚫 @@ -662,9 +547,6 @@ Key: - - - Mute/block: Blocked by user @@ -672,11 +554,9 @@ Key: - - 🚫 @@ -684,9 +564,6 @@ Key: - - - Mute/block: Muted user @@ -694,21 +571,15 @@ Key: - - - - - - Mute/block: Muted-by-list user @@ -716,20 +587,15 @@ Key: - - - - - ScenarioFilterAccountProfileAvatar Prioritization: blocking & blocked-by user @@ -738,11 +604,9 @@ Key: - - 🚫 @@ -750,9 +614,6 @@ Key: - - - Prioritization: '!hide' label on account of blocked user @@ -764,7 +625,6 @@ Key: - 🚫 @@ -772,9 +632,6 @@ Key: - - - Prioritization: '!hide' and 'intolerant' labels on account (hide) @@ -786,7 +643,6 @@ Key: - 🚫 @@ -794,9 +650,6 @@ Key: - - - Prioritization: '!warn' and 'intolerant' labels on account (hide) @@ -808,7 +661,6 @@ Key: - ✋ @@ -816,9 +668,6 @@ Key: - - - Prioritization: '!warn' and 'porn' labels on account (hide) @@ -830,7 +679,6 @@ Key: - ✋ @@ -838,9 +686,6 @@ Key: - - - Prioritization: intolerant label on account (hide) and scam label on profile (warn) @@ -853,6 +698,7 @@ Key: 🪧 + ✋ @@ -860,9 +706,6 @@ Key: - - - Prioritization: !hide on account, !warn on profile @@ -882,9 +725,6 @@ Key: - - - Prioritization: !warn on account, !hide on profile @@ -904,4 +744,4 @@ Key: - \ No newline at end of file + From 970d81506f4790dc3253d38819e7480e3a48f6a0 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 21 Sep 2023 10:51:27 -0500 Subject: [PATCH 14/18] use establish validation pattern --- .../src/api/com/atproto/repo/createRecord.ts | 12 ----------- packages/pds/src/handle/index.ts | 2 +- packages/pds/src/repo/prepare.ts | 4 +++- packages/pds/src/util/explicit-slurs.ts | 21 ------------------- packages/pds/src/util/validation.ts | 5 ----- 5 files changed, 4 insertions(+), 40 deletions(-) delete mode 100644 packages/pds/src/util/explicit-slurs.ts delete mode 100644 packages/pds/src/util/validation.ts diff --git a/packages/pds/src/api/com/atproto/repo/createRecord.ts b/packages/pds/src/api/com/atproto/repo/createRecord.ts index 00d86bebbde..26bc5614785 100644 --- a/packages/pds/src/api/com/atproto/repo/createRecord.ts +++ b/packages/pds/src/api/com/atproto/repo/createRecord.ts @@ -1,6 +1,5 @@ import { CID } from 'multiformats/cid' import { InvalidRequestError, AuthRequiredError } from '@atproto/xrpc-server' -import { AppBskyFeedPost } from '@atproto/api' import { prepareCreate } from '../../../../repo' import { Server } from '../../../../lexicon' import { @@ -13,7 +12,6 @@ import AppContext from '../../../../context' import { ids } from '../../../../lexicon/lexicons' import Database from '../../../../db' import { ConcurrentWriteError } from '../../../../services/repo' -import { isValidHashtag } from '../../../../util/validation' export default function (server: Server, ctx: AppContext) { server.com.atproto.repo.createRecord({ @@ -46,16 +44,6 @@ export default function (server: Server, ctx: AppContext) { 'Unvalidated writes are not yet supported.', ) } - if (AppBskyFeedPost.isRecord(record)) { - if (record.tags) { - for (const tag of record.tags) { - if (!isValidHashtag(tag)) { - throw new InvalidRequestError(`Invalid hashtag: ${tag}`) - } - } - } - } - const swapCommitCid = swapCommit ? CID.parse(swapCommit) : undefined let write: PreparedCreate diff --git a/packages/pds/src/handle/index.ts b/packages/pds/src/handle/index.ts index 4fadecc5ea4..deae5409945 100644 --- a/packages/pds/src/handle/index.ts +++ b/packages/pds/src/handle/index.ts @@ -1,7 +1,7 @@ import * as ident from '@atproto/syntax' import { InvalidRequestError } from '@atproto/xrpc-server' import { reservedSubdomains } from './reserved' -import { hasExplicitSlur } from '../util/explicit-slurs' +import { hasExplicitSlur } from './explicit-slurs' import AppContext from '../context' export const normalizeAndValidateHandle = async (opts: { diff --git a/packages/pds/src/repo/prepare.ts b/packages/pds/src/repo/prepare.ts index 3bb22914325..2147ef552b6 100644 --- a/packages/pds/src/repo/prepare.ts +++ b/packages/pds/src/repo/prepare.ts @@ -33,7 +33,7 @@ import { } from '../lexicon/types/app/bsky/feed/post' import { isRecord as isList } from '../lexicon/types/app/bsky/graph/list' import { isRecord as isProfile } from '../lexicon/types/app/bsky/actor/profile' -import { hasExplicitSlur } from '../util/explicit-slurs' +import { hasExplicitSlur } from '../handle/explicit-slurs' import { InvalidRequestError } from '@atproto/xrpc-server' // @TODO do this dynamically off of schemas @@ -299,6 +299,8 @@ function assertNoExplicitSlurs(rkey: string, record: RepoRecord) { } else if (isFeedGenerator(record)) { toCheck += ' ' + rkey toCheck += ' ' + record.displayName + } else if (isPost(record)) { + toCheck += record.tags?.join(' ') } if (hasExplicitSlur(toCheck)) { throw new InvalidRecordError('Unacceptable slur in record') diff --git a/packages/pds/src/util/explicit-slurs.ts b/packages/pds/src/util/explicit-slurs.ts deleted file mode 100644 index 534091366f6..00000000000 --- a/packages/pds/src/util/explicit-slurs.ts +++ /dev/null @@ -1,21 +0,0 @@ -// regexes taken from: https://github.com/Blank-Cheque/Slurs -/* eslint-disable no-misleading-character-class */ -const explicitSlurRegexes = [ - /\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][hĤĥȞȟḦḧḢḣḨḩḤḥḪḫH̱ẖĦħⱧⱨꞪɦꞕΗНн][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, - /\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0]{2}[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, - /\b[fḞḟƑƒꞘꞙᵮᶂ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa@4][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{1,2}([ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeiÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ]{1,2}([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, - /\b[kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLlyÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]*\b/, - /\b[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLloÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOoІіa4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{2}(l[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]t|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeaÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ]?|n[ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]|[a4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa]?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, - /[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLloÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOoІіa4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{2}(l[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]t|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ])[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?/, - /\b[tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa4]+[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn]{1,2}([iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]|[yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ])[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/, -] - -export const hasExplicitSlur = (handle: string): boolean => { - return explicitSlurRegexes.some( - (reg) => - reg.test(handle) || - reg.test( - handle.replaceAll('.', '').replaceAll('-', '').replaceAll('_', ''), - ), - ) -} diff --git a/packages/pds/src/util/validation.ts b/packages/pds/src/util/validation.ts deleted file mode 100644 index e7397f22353..00000000000 --- a/packages/pds/src/util/validation.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { hasExplicitSlur } from './explicit-slurs' - -export function isValidHashtag(tag: string) { - return !hasExplicitSlur(tag) -} From d45e02cd4236862ed3011bceb49a3b38e59d3172 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 21 Sep 2023 11:22:10 -0500 Subject: [PATCH 15/18] add changeset (cherry picked from commit fcb6fe7c26144662f791c7900afcd84c7bf1be6b) --- .changeset/three-snakes-turn.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/three-snakes-turn.md diff --git a/.changeset/three-snakes-turn.md b/.changeset/three-snakes-turn.md new file mode 100644 index 00000000000..cd086115761 --- /dev/null +++ b/.changeset/three-snakes-turn.md @@ -0,0 +1,7 @@ +--- +'@atproto/bsky': patch +'@atproto/api': patch +'@atproto/pds': patch +--- + +Introduce general support for tags on posts From 61875861572462430579c439fe816bc7a334d555 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 22 Sep 2023 14:50:14 -0500 Subject: [PATCH 16/18] remove tags from postView, codegen --- lexicons/app/bsky/feed/defs.json | 6 +----- packages/api/src/client/lexicons.ts | 6 ------ packages/api/src/client/types/app/bsky/feed/defs.ts | 1 - packages/bsky/src/lexicon/lexicons.ts | 6 ------ packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts | 1 - packages/pds/src/lexicon/lexicons.ts | 6 ------ packages/pds/src/lexicon/types/app/bsky/feed/defs.ts | 1 - packages/pds/tests/create-post.test.ts | 2 +- 8 files changed, 2 insertions(+), 27 deletions(-) diff --git a/lexicons/app/bsky/feed/defs.json b/lexicons/app/bsky/feed/defs.json index 7e377a8f1d4..10f2812ce24 100644 --- a/lexicons/app/bsky/feed/defs.json +++ b/lexicons/app/bsky/feed/defs.json @@ -31,11 +31,7 @@ "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, - "threadgate": { "type": "ref", "ref": "#threadgateView" }, - "tags": { - "type": "array", - "items": { "type": "string" } - } + "threadgate": { "type": "ref", "ref": "#threadgateView" } } }, "viewerState": { diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 814fd58736f..a5cbf08d608 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -4443,12 +4443,6 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, - tags: { - type: 'array', - items: { - type: 'string', - }, - }, }, }, viewerState: { diff --git a/packages/api/src/client/types/app/bsky/feed/defs.ts b/packages/api/src/client/types/app/bsky/feed/defs.ts index d11917d2739..944fd34b072 100644 --- a/packages/api/src/client/types/app/bsky/feed/defs.ts +++ b/packages/api/src/client/types/app/bsky/feed/defs.ts @@ -32,7 +32,6 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView - tags?: string[] [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 814fd58736f..a5cbf08d608 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -4443,12 +4443,6 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, - tags: { - type: 'array', - items: { - type: 'string', - }, - }, }, }, viewerState: { diff --git a/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts b/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts index 09a198de442..08d34d88ebb 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/feed/defs.ts @@ -32,7 +32,6 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView - tags?: string[] [k: string]: unknown } diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 814fd58736f..a5cbf08d608 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -4443,12 +4443,6 @@ export const schemaDict = { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, - tags: { - type: 'array', - items: { - type: 'string', - }, - }, }, }, viewerState: { diff --git a/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts b/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts index 09a198de442..08d34d88ebb 100644 --- a/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts +++ b/packages/pds/src/lexicon/types/app/bsky/feed/defs.ts @@ -32,7 +32,6 @@ export interface PostView { viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView - tags?: string[] [k: string]: unknown } diff --git a/packages/pds/tests/create-post.test.ts b/packages/pds/tests/create-post.test.ts index 7f9403d71c5..e2763981fb0 100644 --- a/packages/pds/tests/create-post.test.ts +++ b/packages/pds/tests/create-post.test.ts @@ -36,7 +36,7 @@ describe('pds posts record creation', () => { ) const { value: record } = await agent.api.app.bsky.feed.post.get({ repo: sc.dids.alice, - rkey: new AtUri(res.uri).rkey + rkey: new AtUri(res.uri).rkey, }) expect(record).toBeTruthy() From 41fe4fd9ed276d01caaade241bf1ec36e4aa444d Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 22 Sep 2023 14:56:15 -0500 Subject: [PATCH 17/18] remove tags from thread view --- packages/bsky/src/services/feed/types.ts | 1 - packages/bsky/src/services/feed/views.ts | 1 - packages/bsky/tests/views/thread.test.ts | 26 ------------------------ 3 files changed, 28 deletions(-) diff --git a/packages/bsky/src/services/feed/types.ts b/packages/bsky/src/services/feed/types.ts index a39cc6d2800..8d4bd67f6bb 100644 --- a/packages/bsky/src/services/feed/types.ts +++ b/packages/bsky/src/services/feed/types.ts @@ -45,7 +45,6 @@ export type PostInfo = { invalidReplyRoot: boolean violatesThreadGate: boolean viewer: string | null - tags: string[] | null } export type PostInfoMap = { [uri: string]: PostInfo } diff --git a/packages/bsky/src/services/feed/views.ts b/packages/bsky/src/services/feed/views.ts index 4c2864b20ed..dc5878db6cd 100644 --- a/packages/bsky/src/services/feed/views.ts +++ b/packages/bsky/src/services/feed/views.ts @@ -214,7 +214,6 @@ export class FeedViews { !post.record.reply && gate ? this.formatThreadgate(gate, lists) : undefined, - tags: post.tags ?? undefined, } } diff --git a/packages/bsky/tests/views/thread.test.ts b/packages/bsky/tests/views/thread.test.ts index 6c486acafec..ced4f4533c3 100644 --- a/packages/bsky/tests/views/thread.test.ts +++ b/packages/bsky/tests/views/thread.test.ts @@ -171,32 +171,6 @@ describe('pds thread views', () => { expect(authorSelfLabels).toEqual(['self-label-a', 'self-label-b']) }) - it('returns tags on the thread view', async () => { - const post: AppBskyFeedPost.Record = { - text: 'hello world', - tags: ['javascript', 'hehe'], - createdAt: new Date().toISOString(), - } - - const { uri } = await pdsAgent.api.app.bsky.feed.post.create( - { repo: sc.dids.alice }, - post, - sc.getHeaders(sc.dids.alice), - ) - - await network.processAll() - await network.bsky.processAll() - - const { data } = await agent.api.app.bsky.feed.getPostThread( - { uri }, - { headers: await network.serviceHeaders(bob) }, - ) - - const thread = data.thread as AppBskyFeedDefs.ThreadViewPost - - expect(thread.post.tags).toEqual(post.tags) - }) - describe('takedown', () => { it('blocks post by actor', async () => { const { data: modAction } = From c94f2bab415a19a389829eb43200117413b5063e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 25 Sep 2023 10:33:50 -0500 Subject: [PATCH 18/18] revert unused changes --- packages/bsky/tests/views/thread.test.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/bsky/tests/views/thread.test.ts b/packages/bsky/tests/views/thread.test.ts index ced4f4533c3..d1c96f38603 100644 --- a/packages/bsky/tests/views/thread.test.ts +++ b/packages/bsky/tests/views/thread.test.ts @@ -1,8 +1,4 @@ -import AtpAgent, { - AppBskyFeedGetPostThread, - AppBskyFeedPost, - AppBskyFeedDefs, -} from '@atproto/api' +import AtpAgent, { AppBskyFeedGetPostThread } from '@atproto/api' import { TestNetwork } from '@atproto/dev-env' import { TAKEDOWN } from '@atproto/api/src/client/types/com/atproto/admin/defs' import { forSnapshot, stripViewerFromThread } from '../_util' @@ -14,7 +10,6 @@ import { isThreadViewPost } from '@atproto/api/src/client/types/app/bsky/feed/de describe('pds thread views', () => { let network: TestNetwork let agent: AtpAgent - let pdsAgent: AtpAgent let sc: SeedClient // account dids, for convenience @@ -27,7 +22,7 @@ describe('pds thread views', () => { dbPostgresSchema: 'bsky_views_thread', }) agent = network.bsky.getClient() - pdsAgent = network.pds.getClient() + const pdsAgent = network.pds.getClient() sc = new SeedClient(pdsAgent) await basicSeed(sc) alice = sc.dids.alice