@atproto/bsky 0.0.194 → 0.0.196
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 +27 -0
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +60 -14
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +1 -2
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/auth-verifier.d.ts +1 -0
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +10 -1
- package/dist/auth-verifier.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -0
- package/dist/config.js.map +1 -1
- package/dist/data-plane/server/routes/search.d.ts.map +1 -1
- package/dist/data-plane/server/routes/search.js +15 -1
- package/dist/data-plane/server/routes/search.js.map +1 -1
- package/dist/data-plane/server/util.d.ts +7 -0
- package/dist/data-plane/server/util.d.ts.map +1 -1
- package/dist/data-plane/server/util.js +38 -1
- package/dist/data-plane/server/util.js.map +1 -1
- package/dist/feature-gates.d.ts +17 -6
- package/dist/feature-gates.d.ts.map +1 -1
- package/dist/feature-gates.js +24 -13
- package/dist/feature-gates.js.map +1 -1
- package/dist/hydration/feed.d.ts +4 -1
- package/dist/hydration/feed.d.ts.map +1 -1
- package/dist/hydration/feed.js +10 -2
- package/dist/hydration/feed.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +5 -2
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +17 -3
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +2 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +4 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +98 -28
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +52 -14
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.d.ts +28 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.d.ts.map +1 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.js +7 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.js.map +1 -0
- package/dist/proto/bsky_pb.d.ts +8 -0
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +20 -0
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/views/index.d.ts +6 -4
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +38 -21
- package/dist/views/index.js.map +1 -1
- package/dist/views/threads-v2.d.ts +3 -2
- package/dist/views/threads-v2.d.ts.map +1 -1
- package/dist/views/threads-v2.js +124 -16
- package/dist/views/threads-v2.js.map +1 -1
- package/package.json +7 -7
- package/proto/bsky.proto +2 -0
- package/src/api/app/bsky/feed/searchPosts.ts +78 -11
- package/src/api/app/bsky/unspecced/getPostThreadOtherV2.ts +1 -2
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +4 -1
- package/src/auth-verifier.ts +14 -1
- package/src/config.ts +23 -0
- package/src/data-plane/server/routes/search.ts +18 -1
- package/src/data-plane/server/util.ts +51 -0
- package/src/feature-gates.ts +28 -9
- package/src/hydration/feed.ts +17 -1
- package/src/hydration/hydrator.ts +17 -1
- package/src/index.ts +2 -0
- package/src/lexicon/index.ts +13 -0
- package/src/lexicon/lexicons.ts +52 -16
- package/src/lexicon/types/app/bsky/actor/defs.ts +0 -2
- package/src/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.ts +0 -2
- package/src/lexicon/types/app/bsky/unspecced/getPostThreadV2.ts +0 -2
- package/src/lexicon/types/com/atproto/lexicon/resolveLexicon.ts +46 -0
- package/src/proto/bsky_pb.ts +12 -0
- package/src/views/index.ts +54 -44
- package/src/views/threads-v2.ts +158 -25
- package/tests/utils.test.ts +45 -0
- package/tests/views/post-search.test.ts +221 -0
- package/tests/views/thread-v2.test.ts +2 -109
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @atproto/bsky
|
|
2
2
|
|
|
3
|
+
## 0.0.196
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4333](https://github.com/bluesky-social/atproto/pull/4333) [`f8e56b387`](https://github.com/bluesky-social/atproto/commit/f8e56b387fcd3bc8405225c1bbdef66ca5dc1591) Thanks [@ThisIsMissEm](https://github.com/ThisIsMissEm)! - Prevent usage of DPoP bound access tokens with bsky.social
|
|
8
|
+
|
|
9
|
+
Using DPoP bound access tokens against the bsky server would already fail, but
|
|
10
|
+
it would fail with a rather misleading error: "InvalidToken: Bad token scope",
|
|
11
|
+
because the `scope` on a DPoP bound access token is the actual OAuth scopes, not
|
|
12
|
+
the expected `com.atproto.access` string.
|
|
13
|
+
|
|
14
|
+
This change means the entryway explicit checks if the token is a DPoP bound
|
|
15
|
+
access token, and if it is, then it fails with an error "Malformed token: DPoP
|
|
16
|
+
not supported". A similar check is also done with Bearer tokens in the PDS.
|
|
17
|
+
|
|
18
|
+
- [#4330](https://github.com/bluesky-social/atproto/pull/4330) [`3628cebfb`](https://github.com/bluesky-social/atproto/commit/3628cebfbb04ba49f326bbf411a2d15de2900302) Thanks [@mistydemeo](https://github.com/mistydemeo)! - adjust explicit-slurs regex
|
|
19
|
+
|
|
20
|
+
## 0.0.195
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- [#4269](https://github.com/bluesky-social/atproto/pull/4269) [`39b5c08e0`](https://github.com/bluesky-social/atproto/commit/39b5c08e0799468eba0c3bf50f4f5a8104c35f34) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Deprecate and remove `prioritizeFollowedUsers` setting from preferences response types and `getPostThreadV2` query params.
|
|
25
|
+
|
|
26
|
+
- Updated dependencies [[`94ddc8219`](https://github.com/bluesky-social/atproto/commit/94ddc8219c144475df622137ab88895255136eda), [`756ab5d87`](https://github.com/bluesky-social/atproto/commit/756ab5d87fea75e8648a6bdd545d8b441bfb2dd6), [`39b5c08e0`](https://github.com/bluesky-social/atproto/commit/39b5c08e0799468eba0c3bf50f4f5a8104c35f34)]:
|
|
27
|
+
- @atproto/api@0.18.0
|
|
28
|
+
- @atproto/sync@0.1.36
|
|
29
|
+
|
|
3
30
|
## 0.0.194
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"searchPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAShD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAa5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAgCvD"}
|
|
@@ -2,29 +2,38 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = default_1;
|
|
4
4
|
const common_1 = require("@atproto/common");
|
|
5
|
-
const util_1 = require("../../../../
|
|
5
|
+
const util_1 = require("../../../../data-plane/server/util");
|
|
6
|
+
const feature_gates_1 = require("../../../../feature-gates");
|
|
7
|
+
const util_2 = require("../../../../hydration/util");
|
|
6
8
|
const pipeline_1 = require("../../../../pipeline");
|
|
7
9
|
const uris_1 = require("../../../../util/uris");
|
|
8
|
-
const
|
|
10
|
+
const util_3 = require("../../../util");
|
|
9
11
|
function default_1(server, ctx) {
|
|
10
|
-
const searchPosts = (0, pipeline_1.createPipeline)(skeleton, hydration,
|
|
12
|
+
const searchPosts = (0, pipeline_1.createPipeline)(skeleton, hydration, noBlocksOrTagged, presentation);
|
|
11
13
|
server.app.bsky.feed.searchPosts({
|
|
12
14
|
auth: ctx.authVerifier.standardOptional,
|
|
13
15
|
handler: async ({ auth, params, req }) => {
|
|
14
|
-
const viewer =
|
|
16
|
+
const { viewer, isModService } = ctx.authVerifier.parseCreds(auth);
|
|
15
17
|
const labelers = ctx.reqLabelers(req);
|
|
16
|
-
const hydrateCtx = await ctx.hydrator.createContext({
|
|
17
|
-
|
|
18
|
+
const hydrateCtx = await ctx.hydrator.createContext({
|
|
19
|
+
labelers,
|
|
20
|
+
viewer,
|
|
21
|
+
featureGates: ctx.featureGates.checkGates([ctx.featureGates.ids.SearchFilteringExploration], ctx.featureGates.user({ did: viewer ?? '' })),
|
|
22
|
+
});
|
|
23
|
+
const results = await searchPosts({ ...params, hydrateCtx, isModService }, ctx);
|
|
18
24
|
return {
|
|
19
25
|
encoding: 'application/json',
|
|
20
26
|
body: results,
|
|
21
|
-
headers: (0,
|
|
27
|
+
headers: (0, util_3.resHeaders)({ labelers: hydrateCtx.labelers }),
|
|
22
28
|
};
|
|
23
29
|
},
|
|
24
30
|
});
|
|
25
31
|
}
|
|
26
32
|
const skeleton = async (inputs) => {
|
|
27
33
|
const { ctx, params } = inputs;
|
|
34
|
+
const parsedQuery = (0, util_1.parsePostSearchQuery)(params.q, {
|
|
35
|
+
author: params.author,
|
|
36
|
+
});
|
|
28
37
|
if (ctx.searchAgent) {
|
|
29
38
|
// @NOTE cursors won't change on appview swap
|
|
30
39
|
const { data: res } = await ctx.searchAgent.api.app.bsky.unspecced.searchPostsSkeleton({
|
|
@@ -44,7 +53,8 @@ const skeleton = async (inputs) => {
|
|
|
44
53
|
});
|
|
45
54
|
return {
|
|
46
55
|
posts: res.posts.map(({ uri }) => uri),
|
|
47
|
-
cursor: (0,
|
|
56
|
+
cursor: (0, util_2.parseString)(res.cursor),
|
|
57
|
+
parsedQuery,
|
|
48
58
|
};
|
|
49
59
|
}
|
|
50
60
|
const res = await ctx.dataplane.searchPosts({
|
|
@@ -54,24 +64,60 @@ const skeleton = async (inputs) => {
|
|
|
54
64
|
});
|
|
55
65
|
return {
|
|
56
66
|
posts: res.uris,
|
|
57
|
-
cursor: (0,
|
|
67
|
+
cursor: (0, util_2.parseString)(res.cursor),
|
|
68
|
+
parsedQuery,
|
|
58
69
|
};
|
|
59
70
|
};
|
|
60
71
|
const hydration = async (inputs) => {
|
|
61
72
|
const { ctx, params, skeleton } = inputs;
|
|
62
|
-
return ctx.hydrator.hydratePosts(skeleton.posts.map((uri) => ({ uri })), params.hydrateCtx
|
|
73
|
+
return ctx.hydrator.hydratePosts(skeleton.posts.map((uri) => ({ uri })), params.hydrateCtx, undefined, {
|
|
74
|
+
processDynamicTagsForView: params.hydrateCtx.featureGates.get(feature_gates_1.FeatureGateID.SearchFilteringExploration)
|
|
75
|
+
? 'search'
|
|
76
|
+
: undefined,
|
|
77
|
+
});
|
|
63
78
|
};
|
|
64
|
-
const
|
|
65
|
-
const { ctx, skeleton, hydration } = inputs;
|
|
79
|
+
const noBlocksOrTagged = (inputs) => {
|
|
80
|
+
const { ctx, params, skeleton, hydration } = inputs;
|
|
81
|
+
const { parsedQuery } = skeleton;
|
|
66
82
|
skeleton.posts = skeleton.posts.filter((uri) => {
|
|
83
|
+
const post = hydration.posts?.get(uri);
|
|
84
|
+
if (!post)
|
|
85
|
+
return;
|
|
67
86
|
const creator = (0, uris_1.uriToDid)(uri);
|
|
68
|
-
|
|
87
|
+
const isCuratedSearch = params.sort === 'top';
|
|
88
|
+
const isPostByViewer = creator === params.hydrateCtx.viewer;
|
|
89
|
+
// Cases to always show.
|
|
90
|
+
if (isPostByViewer)
|
|
91
|
+
return true;
|
|
92
|
+
if (params.isModService)
|
|
93
|
+
return true;
|
|
94
|
+
// Cases to never show.
|
|
95
|
+
if (ctx.views.viewerBlockExists(creator, hydration))
|
|
96
|
+
return false;
|
|
97
|
+
let tagged = false;
|
|
98
|
+
if (params.hydrateCtx.featureGates.get(feature_gates_1.FeatureGateID.SearchFilteringExploration)) {
|
|
99
|
+
tagged = post.tags.has(ctx.cfg.visibilityTagHide);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
tagged = [...ctx.cfg.searchTagsHide].some((t) => post.tags.has(t));
|
|
103
|
+
}
|
|
104
|
+
// Cases to conditionally show based on tagging.
|
|
105
|
+
if (isCuratedSearch && tagged)
|
|
106
|
+
return false;
|
|
107
|
+
if (!parsedQuery.author && tagged)
|
|
108
|
+
return false;
|
|
109
|
+
return true;
|
|
69
110
|
});
|
|
70
111
|
return skeleton;
|
|
71
112
|
};
|
|
72
113
|
const presentation = (inputs) => {
|
|
73
114
|
const { ctx, skeleton, hydration } = inputs;
|
|
74
|
-
const posts = (0, common_1.mapDefined)(skeleton.posts, (uri) =>
|
|
115
|
+
const posts = (0, common_1.mapDefined)(skeleton.posts, (uri) => {
|
|
116
|
+
const post = hydration.posts?.get(uri);
|
|
117
|
+
if (!post)
|
|
118
|
+
return;
|
|
119
|
+
return ctx.views.post(uri, hydration);
|
|
120
|
+
});
|
|
75
121
|
return {
|
|
76
122
|
posts,
|
|
77
123
|
cursor: skeleton.cursor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":";;AAmBA,4BAqBC;AAvCD,4CAA4C;AAI5C,qDAAwD;AAGxD,mDAM6B;AAC7B,gDAAkE;AAElE,wCAA0C;AAE1C,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,WAAW,GAAG,IAAA,yBAAc,EAChC,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QAC/B,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;YACjE,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,IAAA,iBAAU,EAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAwC,EAAE,EAAE;IAClE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAE9B,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,6CAA6C;QAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GACjB,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;YAC/D,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,IAAI,SAAS;SAC9C,CAAC,CAAA;QACJ,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC;YACtC,MAAM,EAAE,IAAA,kBAAW,EAAC,GAAG,CAAC,MAAM,CAAC;SAChC,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC;QAC1C,IAAI,EAAE,MAAM,CAAC,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IACF,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,IAAI;QACf,MAAM,EAAE,IAAA,kBAAW,EAAC,GAAG,CAAC,MAAM,CAAC;KAChC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,MAAmD,EACnD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACxC,OAAO,GAAG,CAAC,QAAQ,CAAC,YAAY,CAC9B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EACtC,MAAM,CAAC,UAAU,CAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,MAA+C,EAAE,EAAE;IACnE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,IAAA,eAAc,EAAC,GAAG,CAAC,CAAA;QACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,MAAsD,EACtD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,MAAM,KAAK,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAC/C,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAC/B,CAAA;IACD,OAAO;QACL,KAAK;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC9B,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { AtpAgent } from '@atproto/api'\nimport { mapDefined } from '@atproto/common'\nimport { AppContext } from '../../../../context'\nimport { DataPlaneClient } from '../../../../data-plane'\nimport { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'\nimport { parseString } from '../../../../hydration/util'\nimport { Server } from '../../../../lexicon'\nimport { QueryParams } from '../../../../lexicon/types/app/bsky/feed/searchPosts'\nimport {\n HydrationFnInput,\n PresentationFnInput,\n RulesFnInput,\n SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris'\nimport { Views } from '../../../../views'\nimport { resHeaders } from '../../../util'\n\nexport default function (server: Server, ctx: AppContext) {\n const searchPosts = createPipeline(\n skeleton,\n hydration,\n noBlocks,\n presentation,\n )\n server.app.bsky.feed.searchPosts({\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const results = await searchPosts({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: SkeletonFnInput<Context, Params>) => {\n const { ctx, params } = inputs\n\n if (ctx.searchAgent) {\n // @NOTE cursors won't change on appview swap\n const { data: res } =\n await ctx.searchAgent.api.app.bsky.unspecced.searchPostsSkeleton({\n q: params.q,\n cursor: params.cursor,\n limit: params.limit,\n author: params.author,\n domain: params.domain,\n lang: params.lang,\n mentions: params.mentions,\n since: params.since,\n sort: params.sort,\n tag: params.tag,\n until: params.until,\n url: params.url,\n viewer: params.hydrateCtx.viewer ?? undefined,\n })\n return {\n posts: res.posts.map(({ uri }) => uri),\n cursor: parseString(res.cursor),\n }\n }\n\n const res = await ctx.dataplane.searchPosts({\n term: params.q,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n posts: res.uris,\n cursor: parseString(res.cursor),\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst noBlocks = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.posts = skeleton.posts.filter((uri) => {\n const creator = creatorFromUri(uri)\n return !ctx.views.viewerBlockExists(creator, hydration)\n })\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) =>\n ctx.views.post(uri, hydration),\n )\n return {\n posts,\n cursor: skeleton.cursor,\n hitsTotal: skeleton.hitsTotal,\n }\n}\n\ntype Context = {\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n searchAgent?: AtpAgent\n}\n\ntype Params = QueryParams & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n posts: string[]\n hitsTotal?: number\n cursor?: string\n}\n"]}
|
|
1
|
+
{"version":3,"file":"searchPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"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","sourcesContent":["import { AtpAgent } from '@atproto/api'\nimport { mapDefined } from '@atproto/common'\nimport { ServerConfig } from '../../../../config'\nimport { AppContext } from '../../../../context'\nimport { DataPlaneClient } from '../../../../data-plane'\nimport {\n PostSearchQuery,\n parsePostSearchQuery,\n} from '../../../../data-plane/server/util'\nimport { FeatureGateID } from '../../../../feature-gates'\nimport { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'\nimport { parseString } from '../../../../hydration/util'\nimport { Server } from '../../../../lexicon'\nimport { QueryParams } from '../../../../lexicon/types/app/bsky/feed/searchPosts'\nimport {\n HydrationFnInput,\n PresentationFnInput,\n RulesFnInput,\n SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris'\nimport { Views } from '../../../../views'\nimport { resHeaders } from '../../../util'\n\nexport default function (server: Server, ctx: AppContext) {\n const searchPosts = createPipeline(\n skeleton,\n hydration,\n noBlocksOrTagged,\n presentation,\n )\n server.app.bsky.feed.searchPosts({\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const { viewer, isModService } = ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n featureGates: ctx.featureGates.checkGates(\n [ctx.featureGates.ids.SearchFilteringExploration],\n ctx.featureGates.user({ did: viewer ?? '' }),\n ),\n })\n const results = await searchPosts(\n { ...params, hydrateCtx, isModService },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: SkeletonFnInput<Context, Params>) => {\n const { ctx, params } = inputs\n const parsedQuery = parsePostSearchQuery(params.q, {\n author: params.author,\n })\n\n if (ctx.searchAgent) {\n // @NOTE cursors won't change on appview swap\n const { data: res } =\n await ctx.searchAgent.api.app.bsky.unspecced.searchPostsSkeleton({\n q: params.q,\n cursor: params.cursor,\n limit: params.limit,\n author: params.author,\n domain: params.domain,\n lang: params.lang,\n mentions: params.mentions,\n since: params.since,\n sort: params.sort,\n tag: params.tag,\n until: params.until,\n url: params.url,\n viewer: params.hydrateCtx.viewer ?? undefined,\n })\n return {\n posts: res.posts.map(({ uri }) => uri),\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n }\n\n const res = await ctx.dataplane.searchPosts({\n term: params.q,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n posts: res.uris,\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n undefined,\n {\n processDynamicTagsForView: params.hydrateCtx.featureGates.get(\n FeatureGateID.SearchFilteringExploration,\n )\n ? 'search'\n : undefined,\n },\n )\n}\n\nconst noBlocksOrTagged = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, params, skeleton, hydration } = inputs\n const { parsedQuery } = skeleton\n\n skeleton.posts = skeleton.posts.filter((uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n const creator = creatorFromUri(uri)\n const isCuratedSearch = params.sort === 'top'\n const isPostByViewer = creator === params.hydrateCtx.viewer\n\n // Cases to always show.\n if (isPostByViewer) return true\n if (params.isModService) return true\n\n // Cases to never show.\n if (ctx.views.viewerBlockExists(creator, hydration)) return false\n\n let tagged = false\n if (\n params.hydrateCtx.featureGates.get(\n FeatureGateID.SearchFilteringExploration,\n )\n ) {\n tagged = post.tags.has(ctx.cfg.visibilityTagHide)\n } else {\n tagged = [...ctx.cfg.searchTagsHide].some((t) => post.tags.has(t))\n }\n\n // Cases to conditionally show based on tagging.\n if (isCuratedSearch && tagged) return false\n if (!parsedQuery.author && tagged) return false\n return true\n })\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n return ctx.views.post(uri, hydration)\n })\n return {\n posts,\n cursor: skeleton.cursor,\n hitsTotal: skeleton.hitsTotal,\n }\n}\n\ntype Context = {\n cfg: ServerConfig\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n searchAgent?: AtpAgent\n}\n\ntype Params = QueryParams & {\n hydrateCtx: HydrateCtx\n isModService: boolean\n}\n\ntype Skeleton = {\n posts: string[]\n hitsTotal?: number\n cursor?: string\n parsedQuery: PostSearchQuery\n}\n"]}
|
|
@@ -66,11 +66,10 @@ const hydration = async (inputs) => {
|
|
|
66
66
|
return ctx.hydrator.hydrateThreadPosts(skeleton.uris.map((uri) => ({ uri })), params.hydrateCtx);
|
|
67
67
|
};
|
|
68
68
|
const presentation = (inputs) => {
|
|
69
|
-
const { ctx,
|
|
69
|
+
const { ctx, skeleton, hydration } = inputs;
|
|
70
70
|
const thread = ctx.views.threadOtherV2(skeleton, hydration, {
|
|
71
71
|
below: BELOW,
|
|
72
72
|
branchingFactor: BRANCHING_FACTOR,
|
|
73
|
-
prioritizeFollowedUsers: params.prioritizeFollowedUsers,
|
|
74
73
|
});
|
|
75
74
|
return { thread };
|
|
76
75
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPostThreadOtherV2.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadOtherV2.ts"],"names":[],"mappings":";;AA0BA,4BA6BC;AArDD,uDAAgF;AAIhF,mDAM6B;AAE7B,wCAA0C;AAE1C,+DAA+D;AAC/D,MAAM,KAAK,GAAG,CAAC,CAAA;AAEf,mEAAmE;AACnE,iFAAiF;AACjF,MAAM,KAAK,GAAG,CAAC,CAAA;AAEf,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAE1B,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,kBAAkB,GAAG,IAAA,yBAAc,EACvC,QAAQ,EACR,SAAS,EACT,kBAAO,EAAE,yHAAyH;IAClI,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;QAC7C,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,sBAAsB;QAC7C,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,eAAe,EAAE,GACjD,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAClD,QAAQ;gBACR,MAAM;gBACN,gBAAgB;gBAChB,eAAe;aAChB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,MAAM,kBAAkB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC;gBAC9D,OAAO,EAAE,IAAA,iBAAU,EAAC;oBAClB,QAAQ,EAAE,UAAU,CAAC,QAAQ;iBAC9B,CAAC;aACH,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAwC,EAAE,EAAE;IAClE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;YACxC,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK;SACb,CAAC,CAAA;QACF,OAAO;YACL,MAAM;YACN,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,IAAA,6BAAgB,EAAC,GAAG,EAAE,iBAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,OAAO;gBACL,MAAM;gBACN,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,MAAmD,EACnD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACxC,OAAO,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EACrC,MAAM,CAAC,UAAU,CAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,MAAsD,EACtD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"getPostThreadOtherV2.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadOtherV2.ts"],"names":[],"mappings":"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","sourcesContent":["import { ServerConfig } from '../../../../config'\nimport { AppContext } from '../../../../context'\nimport { Code, DataPlaneClient, isDataplaneError } from '../../../../data-plane'\nimport { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'\nimport { Server } from '../../../../lexicon'\nimport { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/getPostThreadOtherV2'\nimport {\n HydrationFnInput,\n PresentationFnInput,\n SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline'\nimport { Views } from '../../../../views'\nimport { resHeaders } from '../../../util'\n\n// No parents for hidden replies (it would be the anchor post).\nconst ABOVE = 0\n\n// For hidden replies we don't get more than the top-level replies.\n// To get nested replies, load the thread as one of the hidden replies as anchor.\nconst BELOW = 1\n\n// It doesn't really matter since BELOW is 1, so it will not be used.\nconst BRANCHING_FACTOR = 0\n\nexport default function (server: Server, ctx: AppContext) {\n const getPostThreadOther = createPipeline(\n skeleton,\n hydration,\n noRules, // handled in presentation: 3p block-violating replies are turned to #blockedPost, viewer blocks turned to #notFoundPost.\n presentation,\n )\n server.app.bsky.unspecced.getPostThreadOtherV2({\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, include3pBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n include3pBlocks,\n })\n\n return {\n encoding: 'application/json',\n body: await getPostThreadOther({ ...params, hydrateCtx }, ctx),\n headers: resHeaders({\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: SkeletonFnInput<Context, Params>) => {\n const { ctx, params } = inputs\n const anchor = await ctx.hydrator.resolveUri(params.anchor)\n try {\n const res = await ctx.dataplane.getThread({\n postUri: anchor,\n above: ABOVE,\n below: BELOW,\n })\n return {\n anchor,\n uris: res.uris,\n }\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n return {\n anchor,\n uris: [],\n }\n } else {\n throw err\n }\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydrateThreadPosts(\n skeleton.uris.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const thread = ctx.views.threadOtherV2(skeleton, hydration, {\n below: BELOW,\n branchingFactor: BRANCHING_FACTOR,\n })\n return { thread }\n}\n\ntype Context = {\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n cfg: ServerConfig\n}\n\ntype Params = QueryParams & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n anchor: string\n uris: string[]\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPostThreadV2.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadV2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAa5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"getPostThreadV2.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadV2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAa5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAiCvD"}
|
|
@@ -18,6 +18,7 @@ function default_1(server, ctx) {
|
|
|
18
18
|
viewer,
|
|
19
19
|
includeTakedowns,
|
|
20
20
|
include3pBlocks,
|
|
21
|
+
featureGates: ctx.featureGates.checkGates([ctx.featureGates.ids.ThreadsV2ReplyRankingExploration], ctx.featureGates.user({ did: viewer ?? '' })),
|
|
21
22
|
});
|
|
22
23
|
return {
|
|
23
24
|
encoding: 'application/json',
|
|
@@ -65,7 +66,6 @@ const presentation = (inputs) => {
|
|
|
65
66
|
above: calculateAbove(ctx, params),
|
|
66
67
|
below: calculateBelow(ctx, skeleton.anchor, params),
|
|
67
68
|
branchingFactor: params.branchingFactor,
|
|
68
|
-
prioritizeFollowedUsers: params.prioritizeFollowedUsers,
|
|
69
69
|
sort: params.sort,
|
|
70
70
|
});
|
|
71
71
|
const rootUri = hydration.posts?.get(skeleton.anchor)?.record.reply?.root.uri ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPostThreadV2.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadV2.ts"],"names":[],"mappings":";;AAiBA,
|
|
1
|
+
{"version":3,"file":"getPostThreadV2.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getPostThreadV2.ts"],"names":[],"mappings":"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","sourcesContent":["import { ServerConfig } from '../../../../config'\nimport { AppContext } from '../../../../context'\nimport { Code, DataPlaneClient, isDataplaneError } from '../../../../data-plane'\nimport { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'\nimport { Server } from '../../../../lexicon'\nimport { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/getPostThreadV2'\nimport {\n HydrationFnInput,\n PresentationFnInput,\n SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline'\nimport { postUriToThreadgateUri } from '../../../../util/uris'\nimport { Views } from '../../../../views'\nimport { resHeaders } from '../../../util'\n\nexport default function (server: Server, ctx: AppContext) {\n const getPostThread = createPipeline(\n skeleton,\n hydration,\n noRules, // handled in presentation: 3p block-violating replies are turned to #blockedPost, viewer blocks turned to #notFoundPost.\n presentation,\n )\n server.app.bsky.unspecced.getPostThreadV2({\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, include3pBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n include3pBlocks,\n featureGates: ctx.featureGates.checkGates(\n [ctx.featureGates.ids.ThreadsV2ReplyRankingExploration],\n ctx.featureGates.user({ did: viewer ?? '' }),\n ),\n })\n\n return {\n encoding: 'application/json',\n body: await getPostThread({ ...params, hydrateCtx }, ctx),\n headers: resHeaders({\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: SkeletonFnInput<Context, Params>) => {\n const { ctx, params } = inputs\n const anchor = await ctx.hydrator.resolveUri(params.anchor)\n try {\n const res = await ctx.dataplane.getThread({\n postUri: anchor,\n above: calculateAbove(ctx, params),\n below: calculateBelow(ctx, anchor, params),\n })\n return {\n anchor,\n uris: res.uris,\n }\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n return {\n anchor,\n uris: [],\n }\n } else {\n throw err\n }\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydrateThreadPosts(\n skeleton.uris.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton, hydration } = inputs\n const { hasOtherReplies, thread } = ctx.views.threadV2(skeleton, hydration, {\n above: calculateAbove(ctx, params),\n below: calculateBelow(ctx, skeleton.anchor, params),\n branchingFactor: params.branchingFactor,\n sort: params.sort,\n })\n\n const rootUri =\n hydration.posts?.get(skeleton.anchor)?.record.reply?.root.uri ??\n skeleton.anchor\n const threadgate = ctx.views.threadgate(\n postUriToThreadgateUri(rootUri),\n hydration,\n )\n return { hasOtherReplies, thread, threadgate }\n}\n\ntype Context = {\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n cfg: ServerConfig\n}\n\ntype Params = QueryParams & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n anchor: string\n uris: string[]\n}\n\nconst calculateAbove = (ctx: Context, params: Params) => {\n return params.above ? ctx.cfg.maxThreadParents : 0\n}\n\nconst calculateBelow = (ctx: Context, anchor: string, params: Params) => {\n let maxDepth = ctx.cfg.maxThreadDepth\n if (ctx.cfg.bigThreadUris.has(anchor) && ctx.cfg.bigThreadDepth) {\n maxDepth = ctx.cfg.bigThreadDepth\n }\n return maxDepth ? Math.min(maxDepth, params.below) : params.below\n}\n"]}
|
package/dist/auth-verifier.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-verifier.d.ts","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,OAAO,MAAM,SAAS,CAAA;AAK7B,OAAO,EAEL,wBAAwB,EAIzB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAEL,eAAe,EAIhB,MAAM,cAAc,CAAA;AAGrB,KAAK,MAAM,GAAG;IACZ,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;CACrB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CACxC,CAAA;AAED,oBAAY,UAAU;IACpB,KAAK,IAAA;IACL,OAAO,IAAA;IACP,OAAO,IAAA;CACR;AAED,KAAK,UAAU,GAAG;IAChB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,IAAI,CAAA;KACV,CAAA;CACF,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,UAAU,CAAA;QAChB,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,OAAO,CAAA;KACf,CAAA;CACF,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE;QACX,IAAI,EAAE,aAAa,CAAA;QACnB,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAQD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,oBAAoB,CAAC,EAAE,SAAS,CAAA;CACjC,CAAA;AAED,qBAAa,YAAY;IAQd,SAAS,EAAE,eAAe;IAP5B,MAAM,EAAE,MAAM,CAAA;IACd,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACjC,aAAa,EAAE,MAAM,CAAA;IAC5B,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,oBAAoB,CAAC,CAAW;gBAG/B,SAAS,EAAE,eAAe,EACjC,IAAI,EAAE,gBAAgB;IAaxB,6BAA6B,GAC1B,MAAM,gBAAgB,MAChB,KAAK,MAAM,KAAG,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC,CA+CxD;IAEH,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC,CAC/B;IAExC,QAAQ,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,cAAc,CAAC,CAMtD;IAED,IAAI,GAAI,KAAK,MAAM,KAAG,UAAU,CAW/B;IAED,cAAc,GACZ,KAAK,MAAM,KACV,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC,CAMtC;IAED,sBAAsB,GACpB,KAAK,MAAM,KACV,OAAO,CAAC,cAAc,GAAG,UAAU,GAAG,UAAU,CAAC,CAkBnD;IAKD,eAAe,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"auth-verifier.d.ts","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/auth-verifier.js
CHANGED
|
@@ -244,7 +244,12 @@ class AuthVerifier {
|
|
|
244
244
|
}
|
|
245
245
|
throw new xrpc_server_1.AuthRequiredError('Token could not be verified', 'InvalidToken');
|
|
246
246
|
});
|
|
247
|
-
const { sub, aud, scope } = res.payload;
|
|
247
|
+
const { sub, aud, scope, cnf } = res.payload;
|
|
248
|
+
if (typeof cnf !== 'undefined') {
|
|
249
|
+
// Proof-of-Possession (PoP) tokens are not allowed here
|
|
250
|
+
// https://www.rfc-editor.org/rfc/rfc7800.html
|
|
251
|
+
throw new xrpc_server_1.AuthRequiredError('Malformed token: DPoP not supported', 'InvalidToken');
|
|
252
|
+
}
|
|
248
253
|
if (typeof sub !== 'string' || !sub.startsWith('did:')) {
|
|
249
254
|
throw new xrpc_server_1.AuthRequiredError('Malformed token', 'InvalidToken');
|
|
250
255
|
}
|
|
@@ -380,11 +385,15 @@ class AuthVerifier {
|
|
|
380
385
|
this.isModService(creds.credentials.iss));
|
|
381
386
|
const canPerformTakedown = (creds.credentials.type === 'role' && creds.credentials.admin) ||
|
|
382
387
|
creds.credentials.type === 'mod_service';
|
|
388
|
+
const isModService = creds.credentials.type === 'mod_service' ||
|
|
389
|
+
(creds.credentials.type === 'standard' &&
|
|
390
|
+
this.isModService(creds.credentials.iss));
|
|
383
391
|
return {
|
|
384
392
|
viewer,
|
|
385
393
|
includeTakedowns: includeTakedownsAnd3pBlocks,
|
|
386
394
|
include3pBlocks: includeTakedownsAnd3pBlocks,
|
|
387
395
|
canPerformTakedown,
|
|
396
|
+
isModService,
|
|
388
397
|
};
|
|
389
398
|
}
|
|
390
399
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-verifier.js","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto, { KeyObject } from 'node:crypto'\nimport express from 'express'\nimport * as jose from 'jose'\nimport KeyEncoder from 'key-encoder'\nimport * as ui8 from 'uint8arrays'\nimport { SECP256K1_JWT_ALG, parseDidKey } from '@atproto/crypto'\nimport {\n AuthRequiredError,\n VerifySignatureWithKeyFn,\n cryptoVerifySignatureWithKey,\n parseReqNsid,\n verifyJwt as verifyServiceJwt,\n} from '@atproto/xrpc-server'\nimport {\n Code,\n DataPlaneClient,\n getKeyAsDidKey,\n isDataplaneError,\n unpackIdentityKeys,\n} from './data-plane'\nimport { GetIdentityByDidResponse } from './proto/bsky_pb'\n\ntype ReqCtx = {\n req: express.Request\n}\n\ntype StandardAuthOpts = {\n skipAudCheck?: boolean\n lxmCheck?: (method?: string) => boolean\n}\n\nexport enum RoleStatus {\n Valid,\n Invalid,\n Missing,\n}\n\ntype NullOutput = {\n credentials: {\n type: 'none'\n iss: null\n }\n}\n\ntype StandardOutput = {\n credentials: {\n type: 'standard'\n aud: string\n iss: string\n }\n}\n\ntype RoleOutput = {\n credentials: {\n type: 'role'\n admin: boolean\n }\n}\n\ntype ModServiceOutput = {\n credentials: {\n type: 'mod_service'\n aud: string\n iss: string\n }\n}\n\nconst ALLOWED_AUTH_SCOPES = new Set([\n 'com.atproto.access',\n 'com.atproto.appPass',\n 'com.atproto.appPassPrivileged',\n])\n\nexport type AuthVerifierOpts = {\n ownDid: string\n alternateAudienceDids: string[]\n modServiceDid: string\n adminPasses: string[]\n entrywayJwtPublicKey?: KeyObject\n}\n\nexport class AuthVerifier {\n public ownDid: string\n public standardAudienceDids: Set<string>\n public modServiceDid: string\n private adminPasses: Set<string>\n private entrywayJwtPublicKey?: KeyObject\n\n constructor(\n public dataplane: DataPlaneClient,\n opts: AuthVerifierOpts,\n ) {\n this.ownDid = opts.ownDid\n this.standardAudienceDids = new Set([\n opts.ownDid,\n ...opts.alternateAudienceDids,\n ])\n this.modServiceDid = opts.modServiceDid\n this.adminPasses = new Set(opts.adminPasses)\n this.entrywayJwtPublicKey = opts.entrywayJwtPublicKey\n }\n\n // verifiers (arrow fns to preserve scope)\n standardOptionalParameterized =\n (opts: StandardAuthOpts) =>\n async (ctx: ReqCtx): Promise<StandardOutput | NullOutput> => {\n // @TODO remove! basic auth + did supported just for testing.\n if (isBasicToken(ctx.req)) {\n const aud = this.ownDid\n const iss = ctx.req.headers['appview-as-did']\n if (typeof iss !== 'string' || !iss.startsWith('did:')) {\n throw new AuthRequiredError('bad issuer')\n }\n if (!this.parseRoleCreds(ctx.req).admin) {\n throw new AuthRequiredError('bad credentials')\n }\n return {\n credentials: { type: 'standard', iss, aud },\n }\n } else if (isBearerToken(ctx.req)) {\n // @NOTE temporarily accept entryway session tokens to shed load from PDS instances\n const token = bearerTokenFromReq(ctx.req)\n const header = token ? jose.decodeProtectedHeader(token) : undefined\n if (header?.typ === 'at+jwt') {\n // we should never use entryway session tokens in the case of flexible auth audiences (namely in the case of getFeed)\n if (opts.skipAudCheck) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n }\n return this.entrywaySession(ctx)\n }\n\n const { iss, aud } = await this.verifyServiceJwt(ctx, {\n lxmCheck: opts.lxmCheck,\n iss: null,\n aud: null,\n })\n if (!opts.skipAudCheck && !this.standardAudienceDids.has(aud)) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n return {\n credentials: {\n type: 'standard',\n iss,\n aud,\n },\n }\n } else {\n return this.nullCreds()\n }\n }\n\n standardOptional: (ctx: ReqCtx) => Promise<StandardOutput | NullOutput> =\n this.standardOptionalParameterized({})\n\n standard = async (ctx: ReqCtx): Promise<StandardOutput> => {\n const output = await this.standardOptional(ctx)\n if (output.credentials.type === 'none') {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n return output as StandardOutput\n }\n\n role = (ctx: ReqCtx): RoleOutput => {\n const creds = this.parseRoleCreds(ctx.req)\n if (creds.status !== RoleStatus.Valid) {\n throw new AuthRequiredError()\n }\n return {\n credentials: {\n ...creds,\n type: 'role',\n },\n }\n }\n\n standardOrRole = async (\n ctx: ReqCtx,\n ): Promise<StandardOutput | RoleOutput> => {\n if (isBearerToken(ctx.req)) {\n return this.standard(ctx)\n } else {\n return this.role(ctx)\n }\n }\n\n optionalStandardOrRole = async (\n ctx: ReqCtx,\n ): Promise<StandardOutput | RoleOutput | NullOutput> => {\n if (isBearerToken(ctx.req)) {\n return await this.standard(ctx)\n } else {\n const creds = this.parseRoleCreds(ctx.req)\n if (creds.status === RoleStatus.Valid) {\n return {\n credentials: {\n ...creds,\n type: 'role',\n },\n }\n } else if (creds.status === RoleStatus.Missing) {\n return this.nullCreds()\n } else {\n throw new AuthRequiredError()\n }\n }\n }\n\n // @NOTE this auth verifier method is not recommended to be implemented by most appviews\n // this is a short term fix to remove proxy load from Bluesky's PDS and in line with possible\n // future plans to have the client talk directly with the appview\n entrywaySession = async (reqCtx: ReqCtx): Promise<StandardOutput> => {\n const token = bearerTokenFromReq(reqCtx.req)\n if (!token) {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n\n // if entryway jwt key not configured then do not parsed these tokens\n if (!this.entrywayJwtPublicKey) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n }\n\n const res = await jose\n .jwtVerify(token, this.entrywayJwtPublicKey)\n .catch((err) => {\n if (err?.['code'] === 'ERR_JWT_EXPIRED') {\n throw new AuthRequiredError('Token has expired', 'ExpiredToken')\n }\n throw new AuthRequiredError(\n 'Token could not be verified',\n 'InvalidToken',\n )\n })\n\n const { sub, aud, scope } = res.payload\n if (typeof sub !== 'string' || !sub.startsWith('did:')) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n } else if (\n typeof aud !== 'string' ||\n !aud.startsWith('did:web:') ||\n !aud.endsWith('.bsky.network')\n ) {\n throw new AuthRequiredError('Bad token aud', 'InvalidToken')\n } else if (typeof scope !== 'string' || !ALLOWED_AUTH_SCOPES.has(scope)) {\n throw new AuthRequiredError('Bad token scope', 'InvalidToken')\n }\n\n return {\n credentials: {\n type: 'standard',\n aud: this.ownDid,\n iss: sub,\n },\n }\n }\n\n modService = async (reqCtx: ReqCtx): Promise<ModServiceOutput> => {\n const { iss, aud } = await this.verifyServiceJwt(reqCtx, {\n aud: this.ownDid,\n iss: [this.modServiceDid, `${this.modServiceDid}#atproto_labeler`],\n })\n return { credentials: { type: 'mod_service', aud, iss } }\n }\n\n roleOrModService = async (\n reqCtx: ReqCtx,\n ): Promise<RoleOutput | ModServiceOutput> => {\n if (isBearerToken(reqCtx.req)) {\n return this.modService(reqCtx)\n } else {\n return this.role(reqCtx)\n }\n }\n\n parseRoleCreds(req: express.Request) {\n const parsed = parseBasicAuth(req.headers.authorization || '')\n const { Missing, Valid, Invalid } = RoleStatus\n if (!parsed) {\n return { status: Missing, admin: false, moderator: false, triage: false }\n }\n const { username, password } = parsed\n if (username === 'admin' && this.adminPasses.has(password)) {\n return { status: Valid, admin: true }\n }\n return { status: Invalid, admin: false }\n }\n\n async verifyServiceJwt(\n reqCtx: ReqCtx,\n opts: {\n iss: string[] | null\n aud: string | null\n lxmCheck?: (method?: string) => boolean\n },\n ) {\n const getSigningKey = async (\n iss: string,\n _forceRefresh: boolean, // @TODO consider propagating to dataplane\n ): Promise<string> => {\n if (opts.iss !== null && !opts.iss.includes(iss)) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const [did, serviceId] = iss.split('#')\n const keyId =\n serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'\n let identity: GetIdentityByDidResponse\n try {\n identity = await this.dataplane.getIdentityByDid({ did })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new AuthRequiredError('identity unknown')\n }\n throw err\n }\n const keys = unpackIdentityKeys(identity.keys)\n const didKey = getKeyAsDidKey(keys, { id: keyId })\n if (!didKey) {\n throw new AuthRequiredError('missing or bad key')\n }\n return didKey\n }\n const assertLxmCheck = () => {\n const lxm = parseReqNsid(reqCtx.req)\n if (\n (opts.lxmCheck && !opts.lxmCheck(payload.lxm)) ||\n (!opts.lxmCheck && payload.lxm !== lxm)\n ) {\n throw new AuthRequiredError(\n payload.lxm !== undefined\n ? `bad jwt lexicon method (\"lxm\"). must match: ${lxm}`\n : `missing jwt lexicon method (\"lxm\"). must match: ${lxm}`,\n 'BadJwtLexiconMethod',\n )\n }\n }\n\n const jwtStr = bearerTokenFromReq(reqCtx.req)\n if (!jwtStr) {\n throw new AuthRequiredError('missing jwt', 'MissingJwt')\n }\n // if validating additional scopes, skip scope check in initial validation & follow up afterwards\n const payload = await verifyServiceJwt(\n jwtStr,\n opts.aud,\n null,\n getSigningKey,\n verifySignatureWithKey,\n )\n if (\n !payload.iss.endsWith('#atproto_labeler') ||\n payload.lxm !== undefined\n ) {\n // @TODO currently permissive of labelers who dont set lxm yet.\n // we'll allow ozone self-hosters to upgrade before removing this condition.\n assertLxmCheck()\n }\n return { iss: payload.iss, aud: payload.aud }\n }\n\n isModService(iss: string): boolean {\n return [\n this.modServiceDid,\n `${this.modServiceDid}#atproto_labeler`,\n ].includes(iss)\n }\n\n nullCreds(): NullOutput {\n return {\n credentials: {\n type: 'none',\n iss: null,\n },\n }\n }\n\n parseCreds(\n creds: StandardOutput | RoleOutput | ModServiceOutput | NullOutput,\n ) {\n const viewer =\n creds.credentials.type === 'standard' ? creds.credentials.iss : null\n const includeTakedownsAnd3pBlocks =\n (creds.credentials.type === 'role' && creds.credentials.admin) ||\n creds.credentials.type === 'mod_service' ||\n (creds.credentials.type === 'standard' &&\n this.isModService(creds.credentials.iss))\n const canPerformTakedown =\n (creds.credentials.type === 'role' && creds.credentials.admin) ||\n creds.credentials.type === 'mod_service'\n\n return {\n viewer,\n includeTakedowns: includeTakedownsAnd3pBlocks,\n include3pBlocks: includeTakedownsAnd3pBlocks,\n canPerformTakedown,\n }\n }\n}\n\n// HELPERS\n// ---------\n\nconst BEARER = 'Bearer '\nconst BASIC = 'Basic '\n\nconst isBearerToken = (req: express.Request): boolean => {\n return req.headers.authorization?.startsWith(BEARER) ?? false\n}\n\nconst isBasicToken = (req: express.Request): boolean => {\n return req.headers.authorization?.startsWith(BASIC) ?? false\n}\n\nconst bearerTokenFromReq = (req: express.Request) => {\n const header = req.headers.authorization || ''\n if (!header.startsWith(BEARER)) return null\n return header.slice(BEARER.length).trim()\n}\n\nexport const parseBasicAuth = (\n token: string,\n): { username: string; password: string } | null => {\n if (!token.startsWith(BASIC)) return null\n const b64 = token.slice(BASIC.length)\n let parsed: string[]\n try {\n parsed = ui8.toString(ui8.fromString(b64, 'base64pad'), 'utf8').split(':')\n } catch (err) {\n return null\n }\n const [username, password] = parsed\n if (!username || !password) return null\n return { username, password }\n}\n\nexport const buildBasicAuth = (username: string, password: string): string => {\n return (\n BASIC +\n ui8.toString(ui8.fromString(`${username}:${password}`, 'utf8'), 'base64pad')\n )\n}\n\nconst keyEncoder = new KeyEncoder('secp256k1')\nexport const createPublicKeyObject = (publicKeyHex: string): KeyObject => {\n const key = keyEncoder.encodePublic(publicKeyHex, 'raw', 'pem')\n return crypto.createPublicKey({ format: 'pem', key })\n}\n\nconst verifySig = (\n publicKey: Uint8Array,\n data: Uint8Array,\n sig: Uint8Array,\n) => {\n const keyEncoder = new KeyEncoder('secp256k1')\n\n const pemKey = keyEncoder.encodePublic(\n ui8.toString(publicKey, 'hex'),\n 'raw',\n 'pem',\n )\n const key = crypto.createPublicKey({ format: 'pem', key: pemKey })\n\n return crypto.verify(\n 'sha256',\n data,\n {\n key,\n dsaEncoding: 'ieee-p1363',\n },\n sig,\n )\n}\n\nexport const verifySignatureWithKey: VerifySignatureWithKeyFn = async (\n didKey: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => {\n if (alg === SECP256K1_JWT_ALG) {\n const parsed = parseDidKey(didKey)\n if (alg !== parsed.jwtAlg) {\n throw new Error(`Expected key alg ${alg}, got ${parsed.jwtAlg}`)\n }\n\n return verifySig(parsed.keyBytes, msgBytes, sigBytes)\n }\n\n return cryptoVerifySignatureWithKey(didKey, msgBytes, sigBytes, alg)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"auth-verifier.js","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto, { KeyObject } from 'node:crypto'\nimport express from 'express'\nimport * as jose from 'jose'\nimport KeyEncoder from 'key-encoder'\nimport * as ui8 from 'uint8arrays'\nimport { SECP256K1_JWT_ALG, parseDidKey } from '@atproto/crypto'\nimport {\n AuthRequiredError,\n VerifySignatureWithKeyFn,\n cryptoVerifySignatureWithKey,\n parseReqNsid,\n verifyJwt as verifyServiceJwt,\n} from '@atproto/xrpc-server'\nimport {\n Code,\n DataPlaneClient,\n getKeyAsDidKey,\n isDataplaneError,\n unpackIdentityKeys,\n} from './data-plane'\nimport { GetIdentityByDidResponse } from './proto/bsky_pb'\n\ntype ReqCtx = {\n req: express.Request\n}\n\ntype StandardAuthOpts = {\n skipAudCheck?: boolean\n lxmCheck?: (method?: string) => boolean\n}\n\nexport enum RoleStatus {\n Valid,\n Invalid,\n Missing,\n}\n\ntype NullOutput = {\n credentials: {\n type: 'none'\n iss: null\n }\n}\n\ntype StandardOutput = {\n credentials: {\n type: 'standard'\n aud: string\n iss: string\n }\n}\n\ntype RoleOutput = {\n credentials: {\n type: 'role'\n admin: boolean\n }\n}\n\ntype ModServiceOutput = {\n credentials: {\n type: 'mod_service'\n aud: string\n iss: string\n }\n}\n\nconst ALLOWED_AUTH_SCOPES = new Set([\n 'com.atproto.access',\n 'com.atproto.appPass',\n 'com.atproto.appPassPrivileged',\n])\n\nexport type AuthVerifierOpts = {\n ownDid: string\n alternateAudienceDids: string[]\n modServiceDid: string\n adminPasses: string[]\n entrywayJwtPublicKey?: KeyObject\n}\n\nexport class AuthVerifier {\n public ownDid: string\n public standardAudienceDids: Set<string>\n public modServiceDid: string\n private adminPasses: Set<string>\n private entrywayJwtPublicKey?: KeyObject\n\n constructor(\n public dataplane: DataPlaneClient,\n opts: AuthVerifierOpts,\n ) {\n this.ownDid = opts.ownDid\n this.standardAudienceDids = new Set([\n opts.ownDid,\n ...opts.alternateAudienceDids,\n ])\n this.modServiceDid = opts.modServiceDid\n this.adminPasses = new Set(opts.adminPasses)\n this.entrywayJwtPublicKey = opts.entrywayJwtPublicKey\n }\n\n // verifiers (arrow fns to preserve scope)\n standardOptionalParameterized =\n (opts: StandardAuthOpts) =>\n async (ctx: ReqCtx): Promise<StandardOutput | NullOutput> => {\n // @TODO remove! basic auth + did supported just for testing.\n if (isBasicToken(ctx.req)) {\n const aud = this.ownDid\n const iss = ctx.req.headers['appview-as-did']\n if (typeof iss !== 'string' || !iss.startsWith('did:')) {\n throw new AuthRequiredError('bad issuer')\n }\n if (!this.parseRoleCreds(ctx.req).admin) {\n throw new AuthRequiredError('bad credentials')\n }\n return {\n credentials: { type: 'standard', iss, aud },\n }\n } else if (isBearerToken(ctx.req)) {\n // @NOTE temporarily accept entryway session tokens to shed load from PDS instances\n const token = bearerTokenFromReq(ctx.req)\n const header = token ? jose.decodeProtectedHeader(token) : undefined\n if (header?.typ === 'at+jwt') {\n // we should never use entryway session tokens in the case of flexible auth audiences (namely in the case of getFeed)\n if (opts.skipAudCheck) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n }\n return this.entrywaySession(ctx)\n }\n\n const { iss, aud } = await this.verifyServiceJwt(ctx, {\n lxmCheck: opts.lxmCheck,\n iss: null,\n aud: null,\n })\n if (!opts.skipAudCheck && !this.standardAudienceDids.has(aud)) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n return {\n credentials: {\n type: 'standard',\n iss,\n aud,\n },\n }\n } else {\n return this.nullCreds()\n }\n }\n\n standardOptional: (ctx: ReqCtx) => Promise<StandardOutput | NullOutput> =\n this.standardOptionalParameterized({})\n\n standard = async (ctx: ReqCtx): Promise<StandardOutput> => {\n const output = await this.standardOptional(ctx)\n if (output.credentials.type === 'none') {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n return output as StandardOutput\n }\n\n role = (ctx: ReqCtx): RoleOutput => {\n const creds = this.parseRoleCreds(ctx.req)\n if (creds.status !== RoleStatus.Valid) {\n throw new AuthRequiredError()\n }\n return {\n credentials: {\n ...creds,\n type: 'role',\n },\n }\n }\n\n standardOrRole = async (\n ctx: ReqCtx,\n ): Promise<StandardOutput | RoleOutput> => {\n if (isBearerToken(ctx.req)) {\n return this.standard(ctx)\n } else {\n return this.role(ctx)\n }\n }\n\n optionalStandardOrRole = async (\n ctx: ReqCtx,\n ): Promise<StandardOutput | RoleOutput | NullOutput> => {\n if (isBearerToken(ctx.req)) {\n return await this.standard(ctx)\n } else {\n const creds = this.parseRoleCreds(ctx.req)\n if (creds.status === RoleStatus.Valid) {\n return {\n credentials: {\n ...creds,\n type: 'role',\n },\n }\n } else if (creds.status === RoleStatus.Missing) {\n return this.nullCreds()\n } else {\n throw new AuthRequiredError()\n }\n }\n }\n\n // @NOTE this auth verifier method is not recommended to be implemented by most appviews\n // this is a short term fix to remove proxy load from Bluesky's PDS and in line with possible\n // future plans to have the client talk directly with the appview\n entrywaySession = async (reqCtx: ReqCtx): Promise<StandardOutput> => {\n const token = bearerTokenFromReq(reqCtx.req)\n if (!token) {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n\n // if entryway jwt key not configured then do not parsed these tokens\n if (!this.entrywayJwtPublicKey) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n }\n\n const res = await jose\n .jwtVerify(token, this.entrywayJwtPublicKey)\n .catch((err) => {\n if (err?.['code'] === 'ERR_JWT_EXPIRED') {\n throw new AuthRequiredError('Token has expired', 'ExpiredToken')\n }\n throw new AuthRequiredError(\n 'Token could not be verified',\n 'InvalidToken',\n )\n })\n\n const { sub, aud, scope, cnf } = res.payload\n if (typeof cnf !== 'undefined') {\n // Proof-of-Possession (PoP) tokens are not allowed here\n // https://www.rfc-editor.org/rfc/rfc7800.html\n throw new AuthRequiredError(\n 'Malformed token: DPoP not supported',\n 'InvalidToken',\n )\n }\n if (typeof sub !== 'string' || !sub.startsWith('did:')) {\n throw new AuthRequiredError('Malformed token', 'InvalidToken')\n } else if (\n typeof aud !== 'string' ||\n !aud.startsWith('did:web:') ||\n !aud.endsWith('.bsky.network')\n ) {\n throw new AuthRequiredError('Bad token aud', 'InvalidToken')\n } else if (typeof scope !== 'string' || !ALLOWED_AUTH_SCOPES.has(scope)) {\n throw new AuthRequiredError('Bad token scope', 'InvalidToken')\n }\n\n return {\n credentials: {\n type: 'standard',\n aud: this.ownDid,\n iss: sub,\n },\n }\n }\n\n modService = async (reqCtx: ReqCtx): Promise<ModServiceOutput> => {\n const { iss, aud } = await this.verifyServiceJwt(reqCtx, {\n aud: this.ownDid,\n iss: [this.modServiceDid, `${this.modServiceDid}#atproto_labeler`],\n })\n return { credentials: { type: 'mod_service', aud, iss } }\n }\n\n roleOrModService = async (\n reqCtx: ReqCtx,\n ): Promise<RoleOutput | ModServiceOutput> => {\n if (isBearerToken(reqCtx.req)) {\n return this.modService(reqCtx)\n } else {\n return this.role(reqCtx)\n }\n }\n\n parseRoleCreds(req: express.Request) {\n const parsed = parseBasicAuth(req.headers.authorization || '')\n const { Missing, Valid, Invalid } = RoleStatus\n if (!parsed) {\n return { status: Missing, admin: false, moderator: false, triage: false }\n }\n const { username, password } = parsed\n if (username === 'admin' && this.adminPasses.has(password)) {\n return { status: Valid, admin: true }\n }\n return { status: Invalid, admin: false }\n }\n\n async verifyServiceJwt(\n reqCtx: ReqCtx,\n opts: {\n iss: string[] | null\n aud: string | null\n lxmCheck?: (method?: string) => boolean\n },\n ) {\n const getSigningKey = async (\n iss: string,\n _forceRefresh: boolean, // @TODO consider propagating to dataplane\n ): Promise<string> => {\n if (opts.iss !== null && !opts.iss.includes(iss)) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const [did, serviceId] = iss.split('#')\n const keyId =\n serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'\n let identity: GetIdentityByDidResponse\n try {\n identity = await this.dataplane.getIdentityByDid({ did })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new AuthRequiredError('identity unknown')\n }\n throw err\n }\n const keys = unpackIdentityKeys(identity.keys)\n const didKey = getKeyAsDidKey(keys, { id: keyId })\n if (!didKey) {\n throw new AuthRequiredError('missing or bad key')\n }\n return didKey\n }\n const assertLxmCheck = () => {\n const lxm = parseReqNsid(reqCtx.req)\n if (\n (opts.lxmCheck && !opts.lxmCheck(payload.lxm)) ||\n (!opts.lxmCheck && payload.lxm !== lxm)\n ) {\n throw new AuthRequiredError(\n payload.lxm !== undefined\n ? `bad jwt lexicon method (\"lxm\"). must match: ${lxm}`\n : `missing jwt lexicon method (\"lxm\"). must match: ${lxm}`,\n 'BadJwtLexiconMethod',\n )\n }\n }\n\n const jwtStr = bearerTokenFromReq(reqCtx.req)\n if (!jwtStr) {\n throw new AuthRequiredError('missing jwt', 'MissingJwt')\n }\n // if validating additional scopes, skip scope check in initial validation & follow up afterwards\n const payload = await verifyServiceJwt(\n jwtStr,\n opts.aud,\n null,\n getSigningKey,\n verifySignatureWithKey,\n )\n if (\n !payload.iss.endsWith('#atproto_labeler') ||\n payload.lxm !== undefined\n ) {\n // @TODO currently permissive of labelers who dont set lxm yet.\n // we'll allow ozone self-hosters to upgrade before removing this condition.\n assertLxmCheck()\n }\n return { iss: payload.iss, aud: payload.aud }\n }\n\n isModService(iss: string): boolean {\n return [\n this.modServiceDid,\n `${this.modServiceDid}#atproto_labeler`,\n ].includes(iss)\n }\n\n nullCreds(): NullOutput {\n return {\n credentials: {\n type: 'none',\n iss: null,\n },\n }\n }\n\n parseCreds(\n creds: StandardOutput | RoleOutput | ModServiceOutput | NullOutput,\n ) {\n const viewer =\n creds.credentials.type === 'standard' ? creds.credentials.iss : null\n const includeTakedownsAnd3pBlocks =\n (creds.credentials.type === 'role' && creds.credentials.admin) ||\n creds.credentials.type === 'mod_service' ||\n (creds.credentials.type === 'standard' &&\n this.isModService(creds.credentials.iss))\n const canPerformTakedown =\n (creds.credentials.type === 'role' && creds.credentials.admin) ||\n creds.credentials.type === 'mod_service'\n const isModService =\n creds.credentials.type === 'mod_service' ||\n (creds.credentials.type === 'standard' &&\n this.isModService(creds.credentials.iss))\n\n return {\n viewer,\n includeTakedowns: includeTakedownsAnd3pBlocks,\n include3pBlocks: includeTakedownsAnd3pBlocks,\n canPerformTakedown,\n isModService,\n }\n }\n}\n\n// HELPERS\n// ---------\n\nconst BEARER = 'Bearer '\nconst BASIC = 'Basic '\n\nconst isBearerToken = (req: express.Request): boolean => {\n return req.headers.authorization?.startsWith(BEARER) ?? false\n}\n\nconst isBasicToken = (req: express.Request): boolean => {\n return req.headers.authorization?.startsWith(BASIC) ?? false\n}\n\nconst bearerTokenFromReq = (req: express.Request) => {\n const header = req.headers.authorization || ''\n if (!header.startsWith(BEARER)) return null\n return header.slice(BEARER.length).trim()\n}\n\nexport const parseBasicAuth = (\n token: string,\n): { username: string; password: string } | null => {\n if (!token.startsWith(BASIC)) return null\n const b64 = token.slice(BASIC.length)\n let parsed: string[]\n try {\n parsed = ui8.toString(ui8.fromString(b64, 'base64pad'), 'utf8').split(':')\n } catch (err) {\n return null\n }\n const [username, password] = parsed\n if (!username || !password) return null\n return { username, password }\n}\n\nexport const buildBasicAuth = (username: string, password: string): string => {\n return (\n BASIC +\n ui8.toString(ui8.fromString(`${username}:${password}`, 'utf8'), 'base64pad')\n )\n}\n\nconst keyEncoder = new KeyEncoder('secp256k1')\nexport const createPublicKeyObject = (publicKeyHex: string): KeyObject => {\n const key = keyEncoder.encodePublic(publicKeyHex, 'raw', 'pem')\n return crypto.createPublicKey({ format: 'pem', key })\n}\n\nconst verifySig = (\n publicKey: Uint8Array,\n data: Uint8Array,\n sig: Uint8Array,\n) => {\n const keyEncoder = new KeyEncoder('secp256k1')\n\n const pemKey = keyEncoder.encodePublic(\n ui8.toString(publicKey, 'hex'),\n 'raw',\n 'pem',\n )\n const key = crypto.createPublicKey({ format: 'pem', key: pemKey })\n\n return crypto.verify(\n 'sha256',\n data,\n {\n key,\n dsaEncoding: 'ieee-p1363',\n },\n sig,\n )\n}\n\nexport const verifySignatureWithKey: VerifySignatureWithKeyFn = async (\n didKey: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => {\n if (alg === SECP256K1_JWT_ALG) {\n const parsed = parseDidKey(didKey)\n if (alg !== parsed.jwtAlg) {\n throw new Error(`Expected key alg ${alg}, got ${parsed.jwtAlg}`)\n }\n\n return verifySig(parsed.keyBytes, msgBytes, sigBytes)\n }\n\n return cryptoVerifySignatureWithKey(didKey, msgBytes, sigBytes, alg)\n}\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export interface ServerConfigValues {
|
|
|
35
35
|
courierHttpVersion?: '1.1' | '2';
|
|
36
36
|
courierIgnoreBadTls?: boolean;
|
|
37
37
|
searchUrl?: string;
|
|
38
|
+
searchTagsHide: Set<string>;
|
|
38
39
|
suggestionsUrl?: string;
|
|
39
40
|
suggestionsApiKey?: string;
|
|
40
41
|
topicsUrl?: string;
|
|
@@ -59,6 +60,8 @@ export interface ServerConfigValues {
|
|
|
59
60
|
maxThreadParents: number;
|
|
60
61
|
threadTagsHide: Set<string>;
|
|
61
62
|
threadTagsBumpDown: Set<string>;
|
|
63
|
+
visibilityTagHide: string;
|
|
64
|
+
visibilityTagRankPrefix: string;
|
|
62
65
|
notificationsDelayMs?: number;
|
|
63
66
|
clientCheckEmailConfirmed?: boolean;
|
|
64
67
|
topicsEnabled?: boolean;
|
|
@@ -100,6 +103,7 @@ export declare class ServerConfig {
|
|
|
100
103
|
get courierHttpVersion(): "2" | "1.1" | undefined;
|
|
101
104
|
get courierIgnoreBadTls(): boolean | undefined;
|
|
102
105
|
get searchUrl(): string | undefined;
|
|
106
|
+
get searchTagsHide(): Set<string>;
|
|
103
107
|
get suggestionsUrl(): string | undefined;
|
|
104
108
|
get suggestionsApiKey(): string | undefined;
|
|
105
109
|
get topicsUrl(): string | undefined;
|
|
@@ -126,6 +130,8 @@ export declare class ServerConfig {
|
|
|
126
130
|
get maxThreadParents(): number;
|
|
127
131
|
get threadTagsHide(): Set<string>;
|
|
128
132
|
get threadTagsBumpDown(): Set<string>;
|
|
133
|
+
get visibilityTagHide(): string;
|
|
134
|
+
get visibilityTagRankPrefix(): string;
|
|
129
135
|
get notificationsDelayMs(): number;
|
|
130
136
|
get disableSsrfProtection(): boolean;
|
|
131
137
|
get proxyAllowHTTP2(): boolean;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,EAAE,CAAA;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IAEjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,oBAAoB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC,SAAS,EAAE,MAAM,CAAA;IACjB,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnC,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAA;IAErB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAE/B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACnC;AAED,qBAAa,YAAY;IAEX,OAAO,CAAC,GAAG;IADvB,OAAO,CAAC,YAAY,CAAC,CAAQ;gBACT,GAAG,EAAE,kBAAkB;IAE3C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,EAAE,CAAA;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IAEjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,oBAAoB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC,SAAS,EAAE,MAAM,CAAA;IACjB,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnC,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAA;IAErB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,iBAAiB,EAAE,MAAM,CAAA;IACzB,uBAAuB,EAAE,MAAM,CAAA;IAE/B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACnC;AAED,qBAAa,YAAY;IAEX,OAAO,CAAC,GAAG;IADvB,OAAO,CAAC,YAAY,CAAC,CAAQ;gBACT,GAAG,EAAE,kBAAkB;IAE3C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAoQtD,UAAU,CAAC,IAAI,EAAE,MAAM;IAQvB,IAAI,OAAO,uBAEV;IAED,IAAI,SAAS,YAEZ;IAED,IAAI,IAAI,uBAEP;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,SAAS,WAEZ;IAED,IAAI,qBAAqB,aAExB;IAED,IAAI,uBAAuB,uBAE1B;IAED,IAAI,aAAa,8BAEhB;IAED,IAAI,SAAS,aAEZ;IAED,IAAI,0BAA0B,uBAE7B;IAED,IAAI,aAAa,aAEhB;IAED,IAAI,oBAAoB,4BAEvB;IAED,IAAI,qBAAqB,wBAExB;IAED,IAAI,QAAQ,WAEX;IAED,IAAI,WAAW,uBAEd;IAED,IAAI,gBAAgB,4BAEnB;IAED,IAAI,iBAAiB,wBAEpB;IAED,IAAI,UAAU,uBAEb;IAED,IAAI,aAAa,uBAEhB;IAED,IAAI,kBAAkB,4BAErB;IAED,IAAI,mBAAmB,wBAEtB;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,cAAc,gBAEjB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,iBAAiB,uBAEpB;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,YAAY,uBAEf;IAED,IAAI,MAAM,uBAET;IAED,IAAI,uBAAuB,uBAE1B;IAED,IAAI,wBAAwB,uBAE3B;IAED,IAAI,sBAAsB,uBAEzB;IAED,IAAI,2BAA2B,uBAE9B;IAED,IAAI,SAAS,WAEZ;IAED,IAAI,wBAAwB,yBAE3B;IAED,IAAI,cAAc,aAEjB;IAED,IAAI,aAAa,WAEhB;IAED,IAAI,oBAAoB,aAEvB;IAED,IAAI,iBAAiB,uBAEpB;IAED,IAAI,UAAU,uBAEb;IAED,IAAI,UAAU,uBAEb;IAED,IAAI,yBAAyB,wBAE5B;IAED,IAAI,aAAa,wBAEhB;IAED,IAAI,cAAc,qBAEjB;IAED,IAAI,aAAa,gBAEhB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,gBAAgB,WAEnB;IAED,IAAI,cAAc,gBAEjB;IAED,IAAI,kBAAkB,gBAErB;IAED,IAAI,iBAAiB,WAEpB;IAED,IAAI,uBAAuB,WAE1B;IAED,IAAI,oBAAoB,WAEvB;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,GAAG,0BAEN;IAED,IAAI,qBAAqB,gBAExB;CACF"}
|
package/dist/config.js
CHANGED
|
@@ -59,6 +59,7 @@ class ServerConfig {
|
|
|
59
59
|
const searchUrl = process.env.BSKY_SEARCH_URL ||
|
|
60
60
|
process.env.BSKY_SEARCH_ENDPOINT ||
|
|
61
61
|
undefined;
|
|
62
|
+
const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE));
|
|
62
63
|
const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined;
|
|
63
64
|
const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined;
|
|
64
65
|
const topicsUrl = process.env.BSKY_TOPICS_URL || undefined;
|
|
@@ -113,6 +114,8 @@ class ServerConfig {
|
|
|
113
114
|
: 50;
|
|
114
115
|
const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE));
|
|
115
116
|
const threadTagsBumpDown = new Set(envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN));
|
|
117
|
+
const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || '';
|
|
118
|
+
const visibilityTagRankPrefix = process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || '';
|
|
116
119
|
const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS
|
|
117
120
|
? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)
|
|
118
121
|
: 0;
|
|
@@ -177,6 +180,7 @@ class ServerConfig {
|
|
|
177
180
|
dataplaneHttpVersion,
|
|
178
181
|
dataplaneIgnoreBadTls,
|
|
179
182
|
searchUrl,
|
|
183
|
+
searchTagsHide,
|
|
180
184
|
suggestionsUrl,
|
|
181
185
|
suggestionsApiKey,
|
|
182
186
|
topicsUrl,
|
|
@@ -211,6 +215,8 @@ class ServerConfig {
|
|
|
211
215
|
maxThreadParents,
|
|
212
216
|
threadTagsHide,
|
|
213
217
|
threadTagsBumpDown,
|
|
218
|
+
visibilityTagHide,
|
|
219
|
+
visibilityTagRankPrefix,
|
|
214
220
|
notificationsDelayMs,
|
|
215
221
|
disableSsrfProtection,
|
|
216
222
|
proxyAllowHTTP2,
|
|
@@ -294,6 +300,9 @@ class ServerConfig {
|
|
|
294
300
|
get searchUrl() {
|
|
295
301
|
return this.cfg.searchUrl;
|
|
296
302
|
}
|
|
303
|
+
get searchTagsHide() {
|
|
304
|
+
return this.cfg.searchTagsHide;
|
|
305
|
+
}
|
|
297
306
|
get suggestionsUrl() {
|
|
298
307
|
return this.cfg.suggestionsUrl;
|
|
299
308
|
}
|
|
@@ -372,6 +381,12 @@ class ServerConfig {
|
|
|
372
381
|
get threadTagsBumpDown() {
|
|
373
382
|
return this.cfg.threadTagsBumpDown;
|
|
374
383
|
}
|
|
384
|
+
get visibilityTagHide() {
|
|
385
|
+
return this.cfg.visibilityTagHide;
|
|
386
|
+
}
|
|
387
|
+
get visibilityTagRankPrefix() {
|
|
388
|
+
return this.cfg.visibilityTagRankPrefix;
|
|
389
|
+
}
|
|
375
390
|
get notificationsDelayMs() {
|
|
376
391
|
return this.cfg.notificationsDelayMs ?? 0;
|
|
377
392
|
}
|