@atproto/bsky 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/api/com/atproto/moderation/util.d.ts +1 -1
- package/dist/db/index.js +17 -1
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20231213T181744386Z-moderation-subject-appeal.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/tables/moderation.d.ts +3 -1
- package/dist/index.js +213 -32
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +1 -0
- package/dist/lexicon/lexicons.d.ts +35 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +10 -1
- package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/moderation/defs.d.ts +2 -1
- package/dist/services/feed/views.d.ts +1 -1
- package/dist/services/moderation/index.d.ts +7 -2
- package/package.json +5 -5
- package/src/api/app/bsky/feed/getPostThread.ts +4 -3
- package/src/api/app/bsky/feed/getTimeline.ts +54 -0
- package/src/api/com/atproto/admin/queryModerationStatuses.ts +2 -0
- package/src/api/com/atproto/moderation/createReport.ts +14 -3
- package/src/api/com/atproto/moderation/util.ts +2 -0
- package/src/api/health.ts +14 -0
- package/src/auto-moderator/index.ts +19 -0
- package/src/db/migrations/20231213T181744386Z-moderation-subject-appeal.ts +23 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/tables/moderation.ts +3 -0
- package/src/lexicon/index.ts +1 -0
- package/src/lexicon/lexicons.ts +40 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +28 -0
- package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +2 -0
- package/src/lexicon/types/com/atproto/admin/sendEmail.ts +2 -0
- package/src/lexicon/types/com/atproto/moderation/defs.ts +3 -0
- package/src/services/feed/views.ts +6 -3
- package/src/services/moderation/index.ts +9 -0
- package/src/services/moderation/status.ts +24 -0
- package/src/services/moderation/views.ts +2 -0
- package/tests/admin/moderation-appeals.test.ts +269 -0
- package/tests/auto-moderator/labeler.test.ts +39 -0
- package/tests/views/blocks.test.ts +14 -1
- package/tests/views/timeline.test.ts +14 -0
|
@@ -28,3 +28,4 @@ export * as _20230920T213858047Z from './20230920T213858047Z-add-tags-to-post';
|
|
|
28
28
|
export * as _20230929T192920807Z from './20230929T192920807Z-record-cursor-indexes';
|
|
29
29
|
export * as _20231003T202833377Z from './20231003T202833377Z-create-moderation-subject-status';
|
|
30
30
|
export * as _20231205T000257238Z from './20231205T000257238Z-remove-did-cache';
|
|
31
|
+
export * as _20231213T181744386Z from './20231213T181744386Z-moderation-subject-appeal';
|
|
@@ -4,7 +4,7 @@ export declare const eventTableName = "moderation_event";
|
|
|
4
4
|
export declare const subjectStatusTableName = "moderation_subject_status";
|
|
5
5
|
export interface ModerationEvent {
|
|
6
6
|
id: Generated<number>;
|
|
7
|
-
action: 'com.atproto.admin.defs#modEventTakedown' | 'com.atproto.admin.defs#modEventAcknowledge' | 'com.atproto.admin.defs#modEventEscalate' | 'com.atproto.admin.defs#modEventComment' | 'com.atproto.admin.defs#modEventLabel' | 'com.atproto.admin.defs#modEventReport' | 'com.atproto.admin.defs#modEventMute' | 'com.atproto.admin.defs#modEventReverseTakedown' | 'com.atproto.admin.defs#modEventEmail';
|
|
7
|
+
action: 'com.atproto.admin.defs#modEventTakedown' | 'com.atproto.admin.defs#modEventAcknowledge' | 'com.atproto.admin.defs#modEventEscalate' | 'com.atproto.admin.defs#modEventComment' | 'com.atproto.admin.defs#modEventLabel' | 'com.atproto.admin.defs#modEventReport' | 'com.atproto.admin.defs#modEventMute' | 'com.atproto.admin.defs#modEventReverseTakedown' | 'com.atproto.admin.defs#modEventEmail' | 'com.atproto.admin.defs#modEventResolveAppeal';
|
|
8
8
|
subjectType: 'com.atproto.admin.defs#repoRef' | 'com.atproto.repo.strongRef';
|
|
9
9
|
subjectDid: string;
|
|
10
10
|
subjectUri: string | null;
|
|
@@ -31,9 +31,11 @@ export interface ModerationSubjectStatus {
|
|
|
31
31
|
lastReviewedBy: string | null;
|
|
32
32
|
lastReviewedAt: string | null;
|
|
33
33
|
lastReportedAt: string | null;
|
|
34
|
+
lastAppealedAt: string | null;
|
|
34
35
|
muteUntil: string | null;
|
|
35
36
|
suspendUntil: string | null;
|
|
36
37
|
takendown: boolean;
|
|
38
|
+
appealed: boolean | null;
|
|
37
39
|
comment: string | null;
|
|
38
40
|
}
|
|
39
41
|
export declare type PartialDB = {
|
package/dist/index.js
CHANGED
|
@@ -27864,16 +27864,16 @@ var require_validate = __commonJS({
|
|
|
27864
27864
|
const matches = RELATIVE_JSON_POINTER.exec($data);
|
|
27865
27865
|
if (!matches)
|
|
27866
27866
|
throw new Error(`Invalid JSON-pointer: ${$data}`);
|
|
27867
|
-
const
|
|
27867
|
+
const up32 = +matches[1];
|
|
27868
27868
|
jsonPointer = matches[2];
|
|
27869
27869
|
if (jsonPointer === "#") {
|
|
27870
|
-
if (
|
|
27871
|
-
throw new Error(errorMsg("property/index",
|
|
27872
|
-
return dataPathArr[dataLevel -
|
|
27870
|
+
if (up32 >= dataLevel)
|
|
27871
|
+
throw new Error(errorMsg("property/index", up32));
|
|
27872
|
+
return dataPathArr[dataLevel - up32];
|
|
27873
27873
|
}
|
|
27874
|
-
if (
|
|
27875
|
-
throw new Error(errorMsg("data",
|
|
27876
|
-
data = dataNames[dataLevel -
|
|
27874
|
+
if (up32 > dataLevel)
|
|
27875
|
+
throw new Error(errorMsg("data", up32));
|
|
27876
|
+
data = dataNames[dataLevel - up32];
|
|
27877
27877
|
if (!jsonPointer)
|
|
27878
27878
|
return data;
|
|
27879
27879
|
}
|
|
@@ -27886,8 +27886,8 @@ var require_validate = __commonJS({
|
|
|
27886
27886
|
}
|
|
27887
27887
|
}
|
|
27888
27888
|
return expr;
|
|
27889
|
-
function errorMsg(pointerType,
|
|
27890
|
-
return `Cannot access ${pointerType} ${
|
|
27889
|
+
function errorMsg(pointerType, up32) {
|
|
27890
|
+
return `Cannot access ${pointerType} ${up32} levels up, current level is ${dataLevel}`;
|
|
27891
27891
|
}
|
|
27892
27892
|
}
|
|
27893
27893
|
exports.getData = getData;
|
|
@@ -105995,6 +105995,11 @@ var AuthRequiredError = class extends XRPCError2 {
|
|
|
105995
105995
|
super(401 /* AuthRequired */, errorMessage, customErrorName);
|
|
105996
105996
|
}
|
|
105997
105997
|
};
|
|
105998
|
+
var ForbiddenError = class extends XRPCError2 {
|
|
105999
|
+
constructor(errorMessage, customErrorName) {
|
|
106000
|
+
super(403 /* Forbidden */, errorMessage, customErrorName);
|
|
106001
|
+
}
|
|
106002
|
+
};
|
|
105998
106003
|
var RateLimitExceededError = class extends XRPCError2 {
|
|
105999
106004
|
constructor(status, errorMessage, customErrorName) {
|
|
106000
106005
|
super(429 /* RateLimitExceeded */, errorMessage, customErrorName);
|
|
@@ -118840,6 +118845,9 @@ var skeleton = async (params2, ctx) => {
|
|
|
118840
118845
|
if (algorithm && algorithm !== "reverse-chronological" /* ReverseChronological */) {
|
|
118841
118846
|
throw new InvalidRequestError(`Unsupported algorithm: ${algorithm}`);
|
|
118842
118847
|
}
|
|
118848
|
+
if (limit === 1 && !cursor) {
|
|
118849
|
+
return skeletonLimit1(params2, ctx);
|
|
118850
|
+
}
|
|
118843
118851
|
const keyset = new FeedKeyset(ref("feed_item.sortAt"), ref("feed_item.cid"));
|
|
118844
118852
|
const sortFrom = keyset.unpack(cursor)?.primary;
|
|
118845
118853
|
let followQb = db.db.selectFrom("feed_item").innerJoin("follow", "follow.subjectDid", "feed_item.originatorDid").where("follow.creator", "=", viewer).innerJoin("post", "post.uri", "feed_item.postUri").where("feed_item.sortAt", ">", getFeedDateThreshold(sortFrom, 2)).selectAll("feed_item").select([
|
|
@@ -118881,6 +118889,28 @@ var skeleton = async (params2, ctx) => {
|
|
|
118881
118889
|
cursor: keyset.packFromResult(feedItems)
|
|
118882
118890
|
};
|
|
118883
118891
|
};
|
|
118892
|
+
var skeletonLimit1 = async (params2, ctx) => {
|
|
118893
|
+
const { viewer } = params2;
|
|
118894
|
+
const { db } = ctx;
|
|
118895
|
+
const { ref } = db.db.dynamic;
|
|
118896
|
+
const creatorsQb = db.db.selectFrom("follow").where("creator", "=", viewer).select("subjectDid as did").unionAll(sql`select ${viewer} as did`);
|
|
118897
|
+
const feedItemsQb = db.db.selectFrom(creatorsQb.as("creator")).innerJoinLateral((eb) => {
|
|
118898
|
+
const keyset2 = new FeedKeyset(ref("feed_item.sortAt"), ref("feed_item.cid"));
|
|
118899
|
+
const creatorFeedItemQb = eb.selectFrom("feed_item").innerJoin("post", "post.uri", "feed_item.postUri").whereRef("feed_item.originatorDid", "=", "creator.did").where("feed_item.sortAt", ">", getFeedDateThreshold(void 0, 2)).selectAll("feed_item").select([
|
|
118900
|
+
"post.replyRoot",
|
|
118901
|
+
"post.replyParent",
|
|
118902
|
+
"post.creator as postAuthorDid"
|
|
118903
|
+
]);
|
|
118904
|
+
return paginate(creatorFeedItemQb, { limit: 1, keyset: keyset2 }).as("result");
|
|
118905
|
+
}, (join) => join.onTrue()).selectAll("result");
|
|
118906
|
+
const keyset = new FeedKeyset(ref("result.sortAt"), ref("result.cid"));
|
|
118907
|
+
const feedItems = await paginate(feedItemsQb, { limit: 1, keyset }).execute();
|
|
118908
|
+
return {
|
|
118909
|
+
params: params2,
|
|
118910
|
+
feedItems,
|
|
118911
|
+
cursor: keyset.packFromResult(feedItems)
|
|
118912
|
+
};
|
|
118913
|
+
};
|
|
118884
118914
|
var hydration = async (state, ctx) => {
|
|
118885
118915
|
const { feedService } = ctx;
|
|
118886
118916
|
const { params: params2, feedItems } = state;
|
|
@@ -119162,7 +119192,8 @@ var schemaDict = {
|
|
|
119162
119192
|
"lex:com.atproto.admin.defs#modEventLabel",
|
|
119163
119193
|
"lex:com.atproto.admin.defs#modEventAcknowledge",
|
|
119164
119194
|
"lex:com.atproto.admin.defs#modEventEscalate",
|
|
119165
|
-
"lex:com.atproto.admin.defs#modEventMute"
|
|
119195
|
+
"lex:com.atproto.admin.defs#modEventMute",
|
|
119196
|
+
"lex:com.atproto.admin.defs#modEventResolveAppeal"
|
|
119166
119197
|
]
|
|
119167
119198
|
},
|
|
119168
119199
|
subject: {
|
|
@@ -119296,9 +119327,18 @@ var schemaDict = {
|
|
|
119296
119327
|
type: "string",
|
|
119297
119328
|
format: "datetime"
|
|
119298
119329
|
},
|
|
119330
|
+
lastAppealedAt: {
|
|
119331
|
+
type: "string",
|
|
119332
|
+
format: "datetime",
|
|
119333
|
+
description: "Timestamp referencing when the author of the subject appealed a moderation action"
|
|
119334
|
+
},
|
|
119299
119335
|
takendown: {
|
|
119300
119336
|
type: "boolean"
|
|
119301
119337
|
},
|
|
119338
|
+
appealed: {
|
|
119339
|
+
type: "boolean",
|
|
119340
|
+
description: "True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators."
|
|
119341
|
+
},
|
|
119302
119342
|
suspendUntil: {
|
|
119303
119343
|
type: "string",
|
|
119304
119344
|
format: "datetime"
|
|
@@ -119772,6 +119812,16 @@ var schemaDict = {
|
|
|
119772
119812
|
}
|
|
119773
119813
|
}
|
|
119774
119814
|
},
|
|
119815
|
+
modEventResolveAppeal: {
|
|
119816
|
+
type: "object",
|
|
119817
|
+
description: "Resolve appeal on a subject",
|
|
119818
|
+
properties: {
|
|
119819
|
+
comment: {
|
|
119820
|
+
type: "string",
|
|
119821
|
+
description: "Describe resolution."
|
|
119822
|
+
}
|
|
119823
|
+
}
|
|
119824
|
+
},
|
|
119775
119825
|
modEventComment: {
|
|
119776
119826
|
type: "object",
|
|
119777
119827
|
description: "Add a comment to a subject",
|
|
@@ -119870,6 +119920,10 @@ var schemaDict = {
|
|
|
119870
119920
|
subjectLine: {
|
|
119871
119921
|
type: "string",
|
|
119872
119922
|
description: "The subject line of the email sent to the user."
|
|
119923
|
+
},
|
|
119924
|
+
comment: {
|
|
119925
|
+
type: "string",
|
|
119926
|
+
description: "Additional comment about the outgoing comm."
|
|
119873
119927
|
}
|
|
119874
119928
|
}
|
|
119875
119929
|
}
|
|
@@ -120404,6 +120458,10 @@ var schemaDict = {
|
|
|
120404
120458
|
type: "boolean",
|
|
120405
120459
|
description: "Get subjects that were taken down"
|
|
120406
120460
|
},
|
|
120461
|
+
appealed: {
|
|
120462
|
+
type: "boolean",
|
|
120463
|
+
description: "Get subjects in unresolved appealed status"
|
|
120464
|
+
},
|
|
120407
120465
|
limit: {
|
|
120408
120466
|
type: "integer",
|
|
120409
120467
|
minimum: 1,
|
|
@@ -120513,6 +120571,10 @@ var schemaDict = {
|
|
|
120513
120571
|
senderDid: {
|
|
120514
120572
|
type: "string",
|
|
120515
120573
|
format: "did"
|
|
120574
|
+
},
|
|
120575
|
+
comment: {
|
|
120576
|
+
type: "string",
|
|
120577
|
+
description: "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers"
|
|
120516
120578
|
}
|
|
120517
120579
|
}
|
|
120518
120580
|
}
|
|
@@ -120972,7 +121034,8 @@ var schemaDict = {
|
|
|
120972
121034
|
"com.atproto.moderation.defs#reasonMisleading",
|
|
120973
121035
|
"com.atproto.moderation.defs#reasonSexual",
|
|
120974
121036
|
"com.atproto.moderation.defs#reasonRude",
|
|
120975
|
-
"com.atproto.moderation.defs#reasonOther"
|
|
121037
|
+
"com.atproto.moderation.defs#reasonOther",
|
|
121038
|
+
"com.atproto.moderation.defs#reasonAppeal"
|
|
120976
121039
|
]
|
|
120977
121040
|
},
|
|
120978
121041
|
reasonSpam: {
|
|
@@ -120998,6 +121061,10 @@ var schemaDict = {
|
|
|
120998
121061
|
reasonOther: {
|
|
120999
121062
|
type: "token",
|
|
121000
121063
|
description: "Other: reports not falling under another report category"
|
|
121064
|
+
},
|
|
121065
|
+
reasonAppeal: {
|
|
121066
|
+
type: "token",
|
|
121067
|
+
description: "Appeal: appeal a previously taken moderation action"
|
|
121001
121068
|
}
|
|
121002
121069
|
}
|
|
121003
121070
|
},
|
|
@@ -129036,23 +129103,27 @@ var _AtpAgent = class {
|
|
|
129036
129103
|
try {
|
|
129037
129104
|
this.session = session;
|
|
129038
129105
|
const res = await this.api.com.atproto.server.getSession();
|
|
129039
|
-
if (
|
|
129040
|
-
throw new
|
|
129106
|
+
if (res.data.did !== this.session.did) {
|
|
129107
|
+
throw new XRPCError(400 /* InvalidRequest */, "Invalid session", "InvalidDID");
|
|
129041
129108
|
}
|
|
129042
129109
|
this.session.email = res.data.email;
|
|
129043
129110
|
this.session.handle = res.data.handle;
|
|
129044
129111
|
this.session.emailConfirmed = res.data.emailConfirmed;
|
|
129045
129112
|
this._updateApiEndpoint(res.data.didDoc);
|
|
129113
|
+
this._persistSession?.("update", this.session);
|
|
129046
129114
|
return res;
|
|
129047
129115
|
} catch (e) {
|
|
129048
129116
|
this.session = void 0;
|
|
129049
|
-
|
|
129050
|
-
|
|
129051
|
-
|
|
129052
|
-
|
|
129117
|
+
if (e instanceof XRPCError) {
|
|
129118
|
+
if ([1, 408, 425, 429, 500, 502, 503, 504, 522, 524].includes(e.status)) {
|
|
129119
|
+
this._persistSession?.("network-error", void 0);
|
|
129120
|
+
} else {
|
|
129121
|
+
this._persistSession?.("expired", void 0);
|
|
129122
|
+
}
|
|
129053
129123
|
} else {
|
|
129054
|
-
this._persistSession?.("
|
|
129124
|
+
this._persistSession?.("network-error", void 0);
|
|
129055
129125
|
}
|
|
129126
|
+
throw e;
|
|
129056
129127
|
}
|
|
129057
129128
|
}
|
|
129058
129129
|
_addAuthHeader(reqHeaders) {
|
|
@@ -130595,7 +130666,8 @@ var schemaDict2 = {
|
|
|
130595
130666
|
"lex:com.atproto.admin.defs#modEventLabel",
|
|
130596
130667
|
"lex:com.atproto.admin.defs#modEventAcknowledge",
|
|
130597
130668
|
"lex:com.atproto.admin.defs#modEventEscalate",
|
|
130598
|
-
"lex:com.atproto.admin.defs#modEventMute"
|
|
130669
|
+
"lex:com.atproto.admin.defs#modEventMute",
|
|
130670
|
+
"lex:com.atproto.admin.defs#modEventResolveAppeal"
|
|
130599
130671
|
]
|
|
130600
130672
|
},
|
|
130601
130673
|
subject: {
|
|
@@ -130729,9 +130801,18 @@ var schemaDict2 = {
|
|
|
130729
130801
|
type: "string",
|
|
130730
130802
|
format: "datetime"
|
|
130731
130803
|
},
|
|
130804
|
+
lastAppealedAt: {
|
|
130805
|
+
type: "string",
|
|
130806
|
+
format: "datetime",
|
|
130807
|
+
description: "Timestamp referencing when the author of the subject appealed a moderation action"
|
|
130808
|
+
},
|
|
130732
130809
|
takendown: {
|
|
130733
130810
|
type: "boolean"
|
|
130734
130811
|
},
|
|
130812
|
+
appealed: {
|
|
130813
|
+
type: "boolean",
|
|
130814
|
+
description: "True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators."
|
|
130815
|
+
},
|
|
130735
130816
|
suspendUntil: {
|
|
130736
130817
|
type: "string",
|
|
130737
130818
|
format: "datetime"
|
|
@@ -131205,6 +131286,16 @@ var schemaDict2 = {
|
|
|
131205
131286
|
}
|
|
131206
131287
|
}
|
|
131207
131288
|
},
|
|
131289
|
+
modEventResolveAppeal: {
|
|
131290
|
+
type: "object",
|
|
131291
|
+
description: "Resolve appeal on a subject",
|
|
131292
|
+
properties: {
|
|
131293
|
+
comment: {
|
|
131294
|
+
type: "string",
|
|
131295
|
+
description: "Describe resolution."
|
|
131296
|
+
}
|
|
131297
|
+
}
|
|
131298
|
+
},
|
|
131208
131299
|
modEventComment: {
|
|
131209
131300
|
type: "object",
|
|
131210
131301
|
description: "Add a comment to a subject",
|
|
@@ -131303,6 +131394,10 @@ var schemaDict2 = {
|
|
|
131303
131394
|
subjectLine: {
|
|
131304
131395
|
type: "string",
|
|
131305
131396
|
description: "The subject line of the email sent to the user."
|
|
131397
|
+
},
|
|
131398
|
+
comment: {
|
|
131399
|
+
type: "string",
|
|
131400
|
+
description: "Additional comment about the outgoing comm."
|
|
131306
131401
|
}
|
|
131307
131402
|
}
|
|
131308
131403
|
}
|
|
@@ -131837,6 +131932,10 @@ var schemaDict2 = {
|
|
|
131837
131932
|
type: "boolean",
|
|
131838
131933
|
description: "Get subjects that were taken down"
|
|
131839
131934
|
},
|
|
131935
|
+
appealed: {
|
|
131936
|
+
type: "boolean",
|
|
131937
|
+
description: "Get subjects in unresolved appealed status"
|
|
131938
|
+
},
|
|
131840
131939
|
limit: {
|
|
131841
131940
|
type: "integer",
|
|
131842
131941
|
minimum: 1,
|
|
@@ -131946,6 +132045,10 @@ var schemaDict2 = {
|
|
|
131946
132045
|
senderDid: {
|
|
131947
132046
|
type: "string",
|
|
131948
132047
|
format: "did"
|
|
132048
|
+
},
|
|
132049
|
+
comment: {
|
|
132050
|
+
type: "string",
|
|
132051
|
+
description: "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers"
|
|
131949
132052
|
}
|
|
131950
132053
|
}
|
|
131951
132054
|
}
|
|
@@ -132405,7 +132508,8 @@ var schemaDict2 = {
|
|
|
132405
132508
|
"com.atproto.moderation.defs#reasonMisleading",
|
|
132406
132509
|
"com.atproto.moderation.defs#reasonSexual",
|
|
132407
132510
|
"com.atproto.moderation.defs#reasonRude",
|
|
132408
|
-
"com.atproto.moderation.defs#reasonOther"
|
|
132511
|
+
"com.atproto.moderation.defs#reasonOther",
|
|
132512
|
+
"com.atproto.moderation.defs#reasonAppeal"
|
|
132409
132513
|
]
|
|
132410
132514
|
},
|
|
132411
132515
|
reasonSpam: {
|
|
@@ -132431,6 +132535,10 @@ var schemaDict2 = {
|
|
|
132431
132535
|
reasonOther: {
|
|
132432
132536
|
type: "token",
|
|
132433
132537
|
description: "Other: reports not falling under another report category"
|
|
132538
|
+
},
|
|
132539
|
+
reasonAppeal: {
|
|
132540
|
+
type: "token",
|
|
132541
|
+
description: "Appeal: appeal a previously taken moderation action"
|
|
132434
132542
|
}
|
|
132435
132543
|
}
|
|
132436
132544
|
},
|
|
@@ -138483,8 +138591,9 @@ var composeThread = (threadData, actors, state, ctx, viewer) => {
|
|
|
138483
138591
|
const isAnchorPost = state.threadData.post.uri === threadData.post.postUri;
|
|
138484
138592
|
const info = posts[threadData.post.postUri];
|
|
138485
138593
|
const badReply = !!info?.violatesThreadGate;
|
|
138486
|
-
const
|
|
138487
|
-
|
|
138594
|
+
const violatesBlock = (post && blocks[post.uri]?.reply) ?? false;
|
|
138595
|
+
const omitBadReply = !isAnchorPost && (badReply || violatesBlock);
|
|
138596
|
+
if (!post || omitBadReply) {
|
|
138488
138597
|
return {
|
|
138489
138598
|
$type: "app.bsky.feed.defs#notFoundPost",
|
|
138490
138599
|
uri: threadData.post.postUri,
|
|
@@ -138506,7 +138615,7 @@ var composeThread = (threadData, actors, state, ctx, viewer) => {
|
|
|
138506
138615
|
};
|
|
138507
138616
|
}
|
|
138508
138617
|
let parent;
|
|
138509
|
-
if (threadData.parent && !badReply) {
|
|
138618
|
+
if (threadData.parent && !badReply && !violatesBlock) {
|
|
138510
138619
|
if (threadData.parent instanceof ParentNotFoundError) {
|
|
138511
138620
|
parent = {
|
|
138512
138621
|
$type: "app.bsky.feed.defs#notFoundPost",
|
|
@@ -140301,6 +140410,7 @@ var REASONMISLEADING = "com.atproto.moderation.defs#reasonMisleading";
|
|
|
140301
140410
|
var REASONSEXUAL = "com.atproto.moderation.defs#reasonSexual";
|
|
140302
140411
|
var REASONRUDE = "com.atproto.moderation.defs#reasonRude";
|
|
140303
140412
|
var REASONOTHER = "com.atproto.moderation.defs#reasonOther";
|
|
140413
|
+
var REASONAPPEAL = "com.atproto.moderation.defs#reasonAppeal";
|
|
140304
140414
|
|
|
140305
140415
|
// src/lexicon/types/com/atproto/admin/defs.ts
|
|
140306
140416
|
var REVIEWOPEN = "com.atproto.admin.defs#reviewOpen";
|
|
@@ -140369,7 +140479,8 @@ var reasonTypes = /* @__PURE__ */ new Set([
|
|
|
140369
140479
|
REASONMISLEADING,
|
|
140370
140480
|
REASONRUDE,
|
|
140371
140481
|
REASONSEXUAL,
|
|
140372
|
-
REASONVIOLATION
|
|
140482
|
+
REASONVIOLATION,
|
|
140483
|
+
REASONAPPEAL
|
|
140373
140484
|
]);
|
|
140374
140485
|
var eventTypes = /* @__PURE__ */ new Set([
|
|
140375
140486
|
"com.atproto.admin.defs#modEventTakedown",
|
|
@@ -140398,12 +140509,18 @@ function createReport_default(server, ctx) {
|
|
|
140398
140509
|
throw new AuthRequiredError();
|
|
140399
140510
|
}
|
|
140400
140511
|
}
|
|
140512
|
+
const reportReasonType = getReasonType(reasonType);
|
|
140513
|
+
const reportSubject = getSubject(subject);
|
|
140514
|
+
const subjectDid = "did" in reportSubject ? reportSubject.did : reportSubject.uri.host;
|
|
140515
|
+
if (reasonType === REASONAPPEAL && requester !== subjectDid) {
|
|
140516
|
+
throw new ForbiddenError("You cannot appeal this report");
|
|
140517
|
+
}
|
|
140401
140518
|
const report = await db.transaction(async (dbTxn) => {
|
|
140402
140519
|
const moderationTxn = ctx.services.moderation(dbTxn);
|
|
140403
140520
|
return moderationTxn.report({
|
|
140404
|
-
reasonType:
|
|
140521
|
+
reasonType: reportReasonType,
|
|
140405
140522
|
reason,
|
|
140406
|
-
subject:
|
|
140523
|
+
subject: reportSubject,
|
|
140407
140524
|
reportedBy: requester || ctx.cfg.serverDid
|
|
140408
140525
|
});
|
|
140409
140526
|
});
|
|
@@ -140706,6 +140823,7 @@ function queryModerationStatuses_default(server, ctx) {
|
|
|
140706
140823
|
const {
|
|
140707
140824
|
subject,
|
|
140708
140825
|
takendown,
|
|
140826
|
+
appealed,
|
|
140709
140827
|
reviewState,
|
|
140710
140828
|
reviewedAfter,
|
|
140711
140829
|
reviewedBefore,
|
|
@@ -140725,6 +140843,7 @@ function queryModerationStatuses_default(server, ctx) {
|
|
|
140725
140843
|
reviewState: getReviewState(reviewState),
|
|
140726
140844
|
subject,
|
|
140727
140845
|
takendown,
|
|
140846
|
+
appealed,
|
|
140728
140847
|
reviewedAfter,
|
|
140729
140848
|
reviewedBefore,
|
|
140730
140849
|
reportedAfter,
|
|
@@ -140886,6 +141005,14 @@ __export(health_exports, {
|
|
|
140886
141005
|
var import_express2 = __toESM(require_express2());
|
|
140887
141006
|
var createRouter = (ctx) => {
|
|
140888
141007
|
const router = import_express2.default.Router();
|
|
141008
|
+
router.get("/", function(req, res) {
|
|
141009
|
+
res.type("text/plain");
|
|
141010
|
+
res.send('This is an AT Protocol Application View (AppView) for the "bsky.app" application: https://github.com/bluesky-social/atproto\n\nMost API routes are under /xrpc/');
|
|
141011
|
+
});
|
|
141012
|
+
router.get("/robots.txt", function(req, res) {
|
|
141013
|
+
res.type("text/plain");
|
|
141014
|
+
res.send('# Hello Friends!\n\n# Crawling the public parts of the API is allowed. HTTP 429 ("backoff") status codes are used for rate-limiting. Up to a handful concurrent requests should be ok.\nUser-agent: *\nAllow: /');
|
|
141015
|
+
});
|
|
140889
141016
|
router.get("/xrpc/_health", async function(req, res) {
|
|
140890
141017
|
const { version: version2 } = ctx.cfg;
|
|
140891
141018
|
const db = ctx.db.getPrimary();
|
|
@@ -144347,7 +144474,7 @@ var FeedViews = class {
|
|
|
144347
144474
|
for (const item of items) {
|
|
144348
144475
|
const info = posts[item.postUri];
|
|
144349
144476
|
const post = this.formatPostView(item.postUri, actors, posts, threadgates, embeds, labels, lists, viewer);
|
|
144350
|
-
if (!post
|
|
144477
|
+
if (!post) {
|
|
144351
144478
|
continue;
|
|
144352
144479
|
}
|
|
144353
144480
|
const feedPost = { post };
|
|
@@ -144364,8 +144491,8 @@ var FeedViews = class {
|
|
|
144364
144491
|
}
|
|
144365
144492
|
}
|
|
144366
144493
|
if (item.replyParent && item.replyRoot && !info?.invalidReplyRoot && !info?.violatesThreadGate) {
|
|
144367
|
-
const replyParent = this.formatMaybePostView(item.replyParent, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts);
|
|
144368
|
-
const replyRoot = this.formatMaybePostView(item.replyRoot, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts);
|
|
144494
|
+
const replyParent = this.formatMaybePostView(item.replyParent, item.uri, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts);
|
|
144495
|
+
const replyRoot = this.formatMaybePostView(item.replyRoot, item.uri, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts);
|
|
144369
144496
|
if (replyRoot && replyParent) {
|
|
144370
144497
|
feedPost["reply"] = {
|
|
144371
144498
|
root: replyRoot,
|
|
@@ -144440,14 +144567,14 @@ var FeedViews = class {
|
|
|
144440
144567
|
}
|
|
144441
144568
|
return true;
|
|
144442
144569
|
}
|
|
144443
|
-
formatMaybePostView(uri2, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts) {
|
|
144570
|
+
formatMaybePostView(uri2, replyUri, actors, posts, threadgates, embeds, labels, lists, blocks, viewer, opts) {
|
|
144444
144571
|
const post = this.formatPostView(uri2, actors, posts, threadgates, embeds, labels, lists, viewer);
|
|
144445
144572
|
if (!post) {
|
|
144446
144573
|
if (!opts?.usePostViewUnion)
|
|
144447
144574
|
return;
|
|
144448
144575
|
return this.notFoundPost(uri2);
|
|
144449
144576
|
}
|
|
144450
|
-
if (post.author.viewer?.blockedBy || post.author.viewer?.blocking || blocks[
|
|
144577
|
+
if (post.author.viewer?.blockedBy || post.author.viewer?.blocking || replyUri !== null && blocks[replyUri]?.reply) {
|
|
144451
144578
|
if (!opts?.usePostViewUnion)
|
|
144452
144579
|
return;
|
|
144453
144580
|
return this.blockedPost(post);
|
|
@@ -145420,9 +145547,11 @@ var ModerationViews = class {
|
|
|
145420
145547
|
lastReviewedBy: subjectStatus.lastReviewedBy ?? void 0,
|
|
145421
145548
|
lastReviewedAt: subjectStatus.lastReviewedAt ?? void 0,
|
|
145422
145549
|
lastReportedAt: subjectStatus.lastReportedAt ?? void 0,
|
|
145550
|
+
lastAppealedAt: subjectStatus.lastAppealedAt ?? void 0,
|
|
145423
145551
|
muteUntil: subjectStatus.muteUntil ?? void 0,
|
|
145424
145552
|
suspendUntil: subjectStatus.suspendUntil ?? void 0,
|
|
145425
145553
|
takendown: subjectStatus.takendown ?? void 0,
|
|
145554
|
+
appealed: subjectStatus.appealed ?? void 0,
|
|
145426
145555
|
subjectRepoHandle: subjectStatus.handle ?? void 0,
|
|
145427
145556
|
subjectBlobCids: subjectStatus.blobCids || [],
|
|
145428
145557
|
subject: !subjectStatus.recordPath ? {
|
|
@@ -145522,6 +145651,10 @@ var getSubjectStatusForModerationEvent = ({
|
|
|
145522
145651
|
lastReviewedBy: createdBy,
|
|
145523
145652
|
lastReviewedAt: createdAt
|
|
145524
145653
|
};
|
|
145654
|
+
case "com.atproto.admin.defs#modEventResolveAppeal":
|
|
145655
|
+
return {
|
|
145656
|
+
appealed: false
|
|
145657
|
+
};
|
|
145525
145658
|
default:
|
|
145526
145659
|
return null;
|
|
145527
145660
|
}
|
|
@@ -145537,6 +145670,7 @@ var adjustModerationSubjectStatus = async (db, moderationEvent, blobCids) => {
|
|
|
145537
145670
|
comment,
|
|
145538
145671
|
createdAt
|
|
145539
145672
|
} = moderationEvent;
|
|
145673
|
+
const isAppealEvent = action === "com.atproto.admin.defs#modEventReport" && meta?.reportType === REASONAPPEAL;
|
|
145540
145674
|
const subjectStatus = getSubjectStatusForModerationEvent({
|
|
145541
145675
|
action,
|
|
145542
145676
|
createdBy,
|
|
@@ -145566,6 +145700,16 @@ var adjustModerationSubjectStatus = async (db, moderationEvent, blobCids) => {
|
|
|
145566
145700
|
newStatus.takendown = false;
|
|
145567
145701
|
subjectStatus.takendown = false;
|
|
145568
145702
|
}
|
|
145703
|
+
if (isAppealEvent) {
|
|
145704
|
+
newStatus.appealed = true;
|
|
145705
|
+
subjectStatus.appealed = true;
|
|
145706
|
+
newStatus.lastAppealedAt = createdAt;
|
|
145707
|
+
subjectStatus.lastAppealedAt = createdAt;
|
|
145708
|
+
}
|
|
145709
|
+
if (action === "com.atproto.admin.defs#modEventResolveAppeal" && subjectStatus.appealed) {
|
|
145710
|
+
newStatus.appealed = false;
|
|
145711
|
+
subjectStatus.appealed = false;
|
|
145712
|
+
}
|
|
145569
145713
|
if (action === "com.atproto.admin.defs#modEventComment" && meta?.sticky) {
|
|
145570
145714
|
newStatus.comment = comment;
|
|
145571
145715
|
subjectStatus.comment = comment;
|
|
@@ -145977,6 +146121,7 @@ var ModerationService = class {
|
|
|
145977
146121
|
cursor,
|
|
145978
146122
|
limit = 50,
|
|
145979
146123
|
takendown,
|
|
146124
|
+
appealed,
|
|
145980
146125
|
reviewState,
|
|
145981
146126
|
reviewedAfter,
|
|
145982
146127
|
reviewedBefore,
|
|
@@ -146018,6 +146163,9 @@ var ModerationService = class {
|
|
|
146018
146163
|
if (takendown) {
|
|
146019
146164
|
builder = builder.where("takendown", "=", true);
|
|
146020
146165
|
}
|
|
146166
|
+
if (appealed !== void 0) {
|
|
146167
|
+
builder = appealed === null ? builder.where("appealed", "is", null) : builder.where("appealed", "=", appealed);
|
|
146168
|
+
}
|
|
146021
146169
|
if (!includeMuted) {
|
|
146022
146170
|
builder = builder.where((qb) => qb.where("muteUntil", "<", new Date().toISOString()).orWhere("muteUntil", "is", null));
|
|
146023
146171
|
}
|
|
@@ -146807,7 +146955,8 @@ __export(migrations_exports, {
|
|
|
146807
146955
|
_20230920T213858047Z: () => T213858047Z_add_tags_to_post_exports,
|
|
146808
146956
|
_20230929T192920807Z: () => T192920807Z_record_cursor_indexes_exports,
|
|
146809
146957
|
_20231003T202833377Z: () => T202833377Z_create_moderation_subject_status_exports,
|
|
146810
|
-
_20231205T000257238Z: () => T000257238Z_remove_did_cache_exports
|
|
146958
|
+
_20231205T000257238Z: () => T000257238Z_remove_did_cache_exports,
|
|
146959
|
+
_20231213T181744386Z: () => T181744386Z_moderation_subject_appeal_exports
|
|
146811
146960
|
});
|
|
146812
146961
|
|
|
146813
146962
|
// src/db/migrations/20230309T045948368Z-init.ts
|
|
@@ -147343,6 +147492,21 @@ async function down30(db) {
|
|
|
147343
147492
|
await db.schema.createTable("did_cache").addColumn("did", "varchar", (col) => col.primaryKey()).addColumn("doc", "jsonb", (col) => col.notNull()).addColumn("updatedAt", "bigint", (col) => col.notNull()).execute();
|
|
147344
147493
|
}
|
|
147345
147494
|
|
|
147495
|
+
// src/db/migrations/20231213T181744386Z-moderation-subject-appeal.ts
|
|
147496
|
+
var T181744386Z_moderation_subject_appeal_exports = {};
|
|
147497
|
+
__export(T181744386Z_moderation_subject_appeal_exports, {
|
|
147498
|
+
down: () => down31,
|
|
147499
|
+
up: () => up31
|
|
147500
|
+
});
|
|
147501
|
+
async function up31(db) {
|
|
147502
|
+
await db.schema.alterTable("moderation_subject_status").addColumn("lastAppealedAt", "varchar").execute();
|
|
147503
|
+
await db.schema.alterTable("moderation_subject_status").addColumn("appealed", "boolean").execute();
|
|
147504
|
+
}
|
|
147505
|
+
async function down31(db) {
|
|
147506
|
+
await db.schema.alterTable("moderation_subject_status").dropColumn("lastAppealedAt").execute();
|
|
147507
|
+
await db.schema.alterTable("moderation_subject_status").dropColumn("appealed").execute();
|
|
147508
|
+
}
|
|
147509
|
+
|
|
147346
147510
|
// src/db/migrations/provider.ts
|
|
147347
147511
|
var CtxMigrationProvider = class {
|
|
147348
147512
|
constructor(migrations, ctx) {
|
|
@@ -150340,6 +150504,23 @@ var AutoModerator = class {
|
|
|
150340
150504
|
async storeLabels(uri2, cid2, labels) {
|
|
150341
150505
|
if (labels.length < 1)
|
|
150342
150506
|
return;
|
|
150507
|
+
if (this.services.moderation) {
|
|
150508
|
+
await this.ctx.db.transaction(async (dbTxn) => {
|
|
150509
|
+
if (!this.services.moderation)
|
|
150510
|
+
return;
|
|
150511
|
+
const modSrvc = this.services.moderation(dbTxn);
|
|
150512
|
+
await modSrvc.logEvent({
|
|
150513
|
+
event: {
|
|
150514
|
+
$type: "com.atproto.admin.defs#modEventLabel",
|
|
150515
|
+
createLabelVals: labels,
|
|
150516
|
+
negateLabelVals: [],
|
|
150517
|
+
comment: "[AutoModerator]: Applying labels"
|
|
150518
|
+
},
|
|
150519
|
+
subject: { uri: uri2, cid: cid2 },
|
|
150520
|
+
createdBy: this.ctx.cfg.labelerDid
|
|
150521
|
+
});
|
|
150522
|
+
});
|
|
150523
|
+
}
|
|
150343
150524
|
const labelSrvc = this.services.label(this.ctx.db);
|
|
150344
150525
|
await labelSrvc.formatAndCreate(this.ctx.cfg.labelerDid, uri2.toString(), cid2.toString(), { create: labels });
|
|
150345
150526
|
}
|