@atproto/bsky 0.0.36 → 0.0.37
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 +9 -0
- package/dist/auth-verifier.d.ts +9 -8
- package/dist/config.d.ts +4 -0
- package/dist/index.js +85 -24
- package/dist/index.js.map +2 -2
- package/dist/lexicon/lexicons.d.ts +5 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +1 -1
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +1 -0
- package/package.json +5 -5
- package/src/api/blob-resolver.ts +32 -2
- package/src/api/com/atproto/admin/getAccountInfos.ts +1 -1
- package/src/api/com/atproto/admin/getSubjectStatus.ts +1 -1
- package/src/api/com/atproto/admin/updateSubjectStatus.ts +1 -1
- package/src/auth-verifier.ts +42 -21
- package/src/config.ts +21 -0
- package/src/index.ts +1 -1
- package/src/lexicon/lexicons.ts +5 -0
- package/src/lexicon/types/app/bsky/actor/defs.ts +1 -1
- package/src/lexicon/types/com/atproto/admin/defs.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atproto/bsky
|
|
2
2
|
|
|
3
|
+
## 0.0.37
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#2279](https://github.com/bluesky-social/atproto/pull/2279) [`192223f12`](https://github.com/bluesky-social/atproto/commit/192223f127c0b226287df1ecfcd953636db08655) Thanks [@gaearon](https://github.com/gaearon)! - Change Following feed prefs to only show replies from people you follow by default
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`192223f12`](https://github.com/bluesky-social/atproto/commit/192223f127c0b226287df1ecfcd953636db08655)]:
|
|
10
|
+
- @atproto/api@0.10.5
|
|
11
|
+
|
|
3
12
|
## 0.0.36
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/auth-verifier.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare enum RoleStatus {
|
|
|
10
10
|
}
|
|
11
11
|
type NullOutput = {
|
|
12
12
|
credentials: {
|
|
13
|
-
type: '
|
|
13
|
+
type: 'none';
|
|
14
14
|
iss: null;
|
|
15
15
|
};
|
|
16
16
|
};
|
|
@@ -27,22 +27,22 @@ type RoleOutput = {
|
|
|
27
27
|
admin: boolean;
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
|
-
type
|
|
30
|
+
type ModServiceOutput = {
|
|
31
31
|
credentials: {
|
|
32
|
-
type: '
|
|
32
|
+
type: 'mod_service';
|
|
33
33
|
aud: string;
|
|
34
34
|
iss: string;
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
export type AuthVerifierOpts = {
|
|
38
38
|
ownDid: string;
|
|
39
|
-
|
|
39
|
+
modServiceDid: string;
|
|
40
40
|
adminPasses: string[];
|
|
41
41
|
};
|
|
42
42
|
export declare class AuthVerifier {
|
|
43
43
|
dataplane: DataPlaneClient;
|
|
44
44
|
ownDid: string;
|
|
45
|
-
|
|
45
|
+
modServiceDid: string;
|
|
46
46
|
private adminPasses;
|
|
47
47
|
constructor(dataplane: DataPlaneClient, opts: AuthVerifierOpts);
|
|
48
48
|
standard: (ctx: ReqCtx) => Promise<StandardOutput>;
|
|
@@ -51,8 +51,8 @@ export declare class AuthVerifier {
|
|
|
51
51
|
role: (ctx: ReqCtx) => RoleOutput;
|
|
52
52
|
standardOrRole: (ctx: ReqCtx) => Promise<StandardOutput | RoleOutput>;
|
|
53
53
|
optionalStandardOrRole: (ctx: ReqCtx) => Promise<StandardOutput | RoleOutput | NullOutput>;
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
modService: (reqCtx: ReqCtx) => Promise<ModServiceOutput>;
|
|
55
|
+
roleOrModService: (reqCtx: ReqCtx) => Promise<RoleOutput | ModServiceOutput>;
|
|
56
56
|
parseRoleCreds(req: express.Request): {
|
|
57
57
|
status: RoleStatus;
|
|
58
58
|
admin: boolean;
|
|
@@ -71,8 +71,9 @@ export declare class AuthVerifier {
|
|
|
71
71
|
iss: string;
|
|
72
72
|
aud: string;
|
|
73
73
|
}>;
|
|
74
|
+
isModService(iss: string): boolean;
|
|
74
75
|
nullCreds(): NullOutput;
|
|
75
|
-
parseCreds(creds: StandardOutput | RoleOutput |
|
|
76
|
+
parseCreds(creds: StandardOutput | RoleOutput | ModServiceOutput | NullOutput): {
|
|
76
77
|
viewer: string | null;
|
|
77
78
|
canViewTakedowns: boolean;
|
|
78
79
|
canPerformTakedown: boolean;
|
package/dist/config.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface ServerConfigValues {
|
|
|
17
17
|
courierIgnoreBadTls?: boolean;
|
|
18
18
|
searchUrl?: string;
|
|
19
19
|
cdnUrl?: string;
|
|
20
|
+
blobRateLimitBypassKey?: string;
|
|
21
|
+
blobRateLimitBypassHostname?: string;
|
|
20
22
|
didPlcUrl: string;
|
|
21
23
|
handleResolveNameservers?: string[];
|
|
22
24
|
modServiceDid: string;
|
|
@@ -49,6 +51,8 @@ export declare class ServerConfig {
|
|
|
49
51
|
get courierIgnoreBadTls(): boolean | undefined;
|
|
50
52
|
get searchUrl(): string | undefined;
|
|
51
53
|
get cdnUrl(): string | undefined;
|
|
54
|
+
get blobRateLimitBypassKey(): string | undefined;
|
|
55
|
+
get blobRateLimitBypassHostname(): string | undefined;
|
|
52
56
|
get didPlcUrl(): string;
|
|
53
57
|
get handleResolveNameservers(): string[] | undefined;
|
|
54
58
|
get adminPasswords(): string[];
|
package/dist/index.js
CHANGED
|
@@ -132036,6 +132036,9 @@ var getHandle = (doc) => {
|
|
|
132036
132036
|
return found.slice(5);
|
|
132037
132037
|
};
|
|
132038
132038
|
var getSigningKey = (doc) => {
|
|
132039
|
+
return getVerificationMaterial(doc, "atproto");
|
|
132040
|
+
};
|
|
132041
|
+
var getVerificationMaterial = (doc, keyId) => {
|
|
132039
132042
|
const did2 = getDid(doc);
|
|
132040
132043
|
let keys = doc.verificationMethod;
|
|
132041
132044
|
if (!keys)
|
|
@@ -132045,7 +132048,7 @@ var getSigningKey = (doc) => {
|
|
|
132045
132048
|
if (!Array.isArray(keys)) {
|
|
132046
132049
|
keys = [keys];
|
|
132047
132050
|
}
|
|
132048
|
-
const found = keys.find((key) => key.id ===
|
|
132051
|
+
const found = keys.find((key) => key.id === `#${keyId}` || key.id === `${did2}#${keyId}`);
|
|
132049
132052
|
if (!found?.publicKeyMultibase)
|
|
132050
132053
|
return void 0;
|
|
132051
132054
|
return {
|
|
@@ -134406,6 +134409,10 @@ var schemaDict = {
|
|
|
134406
134409
|
type: "string",
|
|
134407
134410
|
description: "The subject line of the email sent to the user."
|
|
134408
134411
|
},
|
|
134412
|
+
content: {
|
|
134413
|
+
type: "string",
|
|
134414
|
+
description: "The content of the email sent to the user."
|
|
134415
|
+
},
|
|
134409
134416
|
comment: {
|
|
134410
134417
|
type: "string",
|
|
134411
134418
|
description: "Additional comment about the outgoing comm."
|
|
@@ -138553,7 +138560,8 @@ var schemaDict = {
|
|
|
138553
138560
|
},
|
|
138554
138561
|
hideRepliesByUnfollowed: {
|
|
138555
138562
|
type: "boolean",
|
|
138556
|
-
description: "Hide replies in the feed if they are not by followed users."
|
|
138563
|
+
description: "Hide replies in the feed if they are not by followed users.",
|
|
138564
|
+
default: true
|
|
138557
138565
|
},
|
|
138558
138566
|
hideRepliesByLikeCount: {
|
|
138559
138567
|
type: "integer",
|
|
@@ -148834,6 +148842,10 @@ var schemaDict2 = {
|
|
|
148834
148842
|
type: "string",
|
|
148835
148843
|
description: "The subject line of the email sent to the user."
|
|
148836
148844
|
},
|
|
148845
|
+
content: {
|
|
148846
|
+
type: "string",
|
|
148847
|
+
description: "The content of the email sent to the user."
|
|
148848
|
+
},
|
|
148837
148849
|
comment: {
|
|
148838
148850
|
type: "string",
|
|
148839
148851
|
description: "Additional comment about the outgoing comm."
|
|
@@ -152981,7 +152993,8 @@ var schemaDict2 = {
|
|
|
152981
152993
|
},
|
|
152982
152994
|
hideRepliesByUnfollowed: {
|
|
152983
152995
|
type: "boolean",
|
|
152984
|
-
description: "Hide replies in the feed if they are not by followed users."
|
|
152996
|
+
description: "Hide replies in the feed if they are not by followed users.",
|
|
152997
|
+
default: true
|
|
152985
152998
|
},
|
|
152986
152999
|
hideRepliesByLikeCount: {
|
|
152987
153000
|
type: "integer",
|
|
@@ -179402,13 +179415,21 @@ var AuthVerifier2 = class {
|
|
|
179402
179415
|
if (!this.parseRoleCreds(ctx.req).admin) {
|
|
179403
179416
|
throw new AuthRequiredError("bad credentials");
|
|
179404
179417
|
}
|
|
179405
|
-
return {
|
|
179418
|
+
return {
|
|
179419
|
+
credentials: { type: "standard", iss: iss2, aud: aud2 }
|
|
179420
|
+
};
|
|
179406
179421
|
}
|
|
179407
179422
|
const { iss, aud } = await this.verifyServiceJwt(ctx, {
|
|
179408
179423
|
aud: this.ownDid,
|
|
179409
179424
|
iss: null
|
|
179410
179425
|
});
|
|
179411
|
-
return {
|
|
179426
|
+
return {
|
|
179427
|
+
credentials: {
|
|
179428
|
+
type: "standard",
|
|
179429
|
+
iss,
|
|
179430
|
+
aud
|
|
179431
|
+
}
|
|
179432
|
+
};
|
|
179412
179433
|
};
|
|
179413
179434
|
this.standardOptional = async (ctx) => {
|
|
179414
179435
|
if (isBearerToken(ctx.req) || isBasicToken(ctx.req)) {
|
|
@@ -179464,22 +179485,22 @@ var AuthVerifier2 = class {
|
|
|
179464
179485
|
}
|
|
179465
179486
|
}
|
|
179466
179487
|
};
|
|
179467
|
-
this.
|
|
179488
|
+
this.modService = async (reqCtx) => {
|
|
179468
179489
|
const { iss, aud } = await this.verifyServiceJwt(reqCtx, {
|
|
179469
179490
|
aud: this.ownDid,
|
|
179470
|
-
iss: [this.
|
|
179491
|
+
iss: [this.modServiceDid, `${this.modServiceDid}#atproto_labeler`]
|
|
179471
179492
|
});
|
|
179472
|
-
return { credentials: { type: "
|
|
179493
|
+
return { credentials: { type: "mod_service", aud, iss } };
|
|
179473
179494
|
};
|
|
179474
|
-
this.
|
|
179495
|
+
this.roleOrModService = async (reqCtx) => {
|
|
179475
179496
|
if (isBearerToken(reqCtx.req)) {
|
|
179476
|
-
return this.
|
|
179497
|
+
return this.modService(reqCtx);
|
|
179477
179498
|
} else {
|
|
179478
179499
|
return this.role(reqCtx);
|
|
179479
179500
|
}
|
|
179480
179501
|
};
|
|
179481
179502
|
this.ownDid = opts.ownDid;
|
|
179482
|
-
this.
|
|
179503
|
+
this.modServiceDid = opts.modServiceDid;
|
|
179483
179504
|
this.adminPasses = new Set(opts.adminPasses);
|
|
179484
179505
|
}
|
|
179485
179506
|
parseRoleCreds(req) {
|
|
@@ -179495,10 +179516,12 @@ var AuthVerifier2 = class {
|
|
|
179495
179516
|
return { status: Invalid, admin: false };
|
|
179496
179517
|
}
|
|
179497
179518
|
async verifyServiceJwt(reqCtx, opts) {
|
|
179498
|
-
const getSigningKey2 = async (
|
|
179499
|
-
if (opts.iss !== null && !opts.iss.includes(
|
|
179519
|
+
const getSigningKey2 = async (iss, _forceRefresh) => {
|
|
179520
|
+
if (opts.iss !== null && !opts.iss.includes(iss)) {
|
|
179500
179521
|
throw new AuthRequiredError("Untrusted issuer", "UntrustedIss");
|
|
179501
179522
|
}
|
|
179523
|
+
const [did2, serviceId] = iss.split("#");
|
|
179524
|
+
const keyId = serviceId === "atproto_labeler" ? "atproto_label" : "atproto";
|
|
179502
179525
|
let identity3;
|
|
179503
179526
|
try {
|
|
179504
179527
|
identity3 = await this.dataplane.getIdentityByDid({ did: did2 });
|
|
@@ -179509,7 +179532,7 @@ var AuthVerifier2 = class {
|
|
|
179509
179532
|
throw err;
|
|
179510
179533
|
}
|
|
179511
179534
|
const keys = unpackIdentityKeys(identity3.keys);
|
|
179512
|
-
const didKey = getKeyAsDidKey(keys, { id:
|
|
179535
|
+
const didKey = getKeyAsDidKey(keys, { id: keyId });
|
|
179513
179536
|
if (!didKey) {
|
|
179514
179537
|
throw new AuthRequiredError("missing or bad key");
|
|
179515
179538
|
}
|
|
@@ -179522,18 +179545,24 @@ var AuthVerifier2 = class {
|
|
|
179522
179545
|
const payload = await verifyJwt(jwtStr, opts.aud, getSigningKey2);
|
|
179523
179546
|
return { iss: payload.iss, aud: payload.aud };
|
|
179524
179547
|
}
|
|
179548
|
+
isModService(iss) {
|
|
179549
|
+
return [
|
|
179550
|
+
this.modServiceDid,
|
|
179551
|
+
`${this.modServiceDid}#atproto_labeler`
|
|
179552
|
+
].includes(iss);
|
|
179553
|
+
}
|
|
179525
179554
|
nullCreds() {
|
|
179526
179555
|
return {
|
|
179527
179556
|
credentials: {
|
|
179528
|
-
type: "
|
|
179557
|
+
type: "none",
|
|
179529
179558
|
iss: null
|
|
179530
179559
|
}
|
|
179531
179560
|
};
|
|
179532
179561
|
}
|
|
179533
179562
|
parseCreds(creds) {
|
|
179534
179563
|
const viewer = creds.credentials.type === "standard" ? creds.credentials.iss : null;
|
|
179535
|
-
const canViewTakedowns = creds.credentials.type === "role" && creds.credentials.admin || creds.credentials.type === "
|
|
179536
|
-
const canPerformTakedown = creds.credentials.type === "role" && creds.credentials.admin || creds.credentials.type === "
|
|
179564
|
+
const canViewTakedowns = creds.credentials.type === "role" && creds.credentials.admin || creds.credentials.type === "mod_service" || creds.credentials.type === "standard" && this.isModService(creds.credentials.iss);
|
|
179565
|
+
const canPerformTakedown = creds.credentials.type === "role" && creds.credentials.admin || creds.credentials.type === "mod_service";
|
|
179537
179566
|
return {
|
|
179538
179567
|
viewer,
|
|
179539
179568
|
canViewTakedowns,
|
|
@@ -183417,7 +183446,7 @@ function getTaggedSuggestions_default(server, ctx) {
|
|
|
183417
183446
|
// src/api/com/atproto/admin/getSubjectStatus.ts
|
|
183418
183447
|
function getSubjectStatus_default(server, ctx) {
|
|
183419
183448
|
server.com.atproto.admin.getSubjectStatus({
|
|
183420
|
-
auth: ctx.authVerifier.
|
|
183449
|
+
auth: ctx.authVerifier.roleOrModService,
|
|
183421
183450
|
handler: async ({ params: params2 }) => {
|
|
183422
183451
|
const { did: did2, uri: uri2, blob: blob2 } = params2;
|
|
183423
183452
|
let body = null;
|
|
@@ -183499,7 +183528,7 @@ function isMain5(v) {
|
|
|
183499
183528
|
// src/api/com/atproto/admin/updateSubjectStatus.ts
|
|
183500
183529
|
function updateSubjectStatus_default(server, ctx) {
|
|
183501
183530
|
server.com.atproto.admin.updateSubjectStatus({
|
|
183502
|
-
auth: ctx.authVerifier.
|
|
183531
|
+
auth: ctx.authVerifier.roleOrModService,
|
|
183503
183532
|
handler: async ({ input, auth }) => {
|
|
183504
183533
|
const { canPerformTakedown } = ctx.authVerifier.parseCreds(auth);
|
|
183505
183534
|
if (!canPerformTakedown) {
|
|
@@ -183567,7 +183596,7 @@ function updateSubjectStatus_default(server, ctx) {
|
|
|
183567
183596
|
// src/api/com/atproto/admin/getAccountInfos.ts
|
|
183568
183597
|
function getAccountInfos_default(server, ctx) {
|
|
183569
183598
|
server.com.atproto.admin.getAccountInfos({
|
|
183570
|
-
auth: ctx.authVerifier.
|
|
183599
|
+
auth: ctx.authVerifier.roleOrModService,
|
|
183571
183600
|
handler: async ({ params: params2 }) => {
|
|
183572
183601
|
const { dids } = params2;
|
|
183573
183602
|
const actors = await ctx.hydrator.actor.getActors(dids, true);
|
|
@@ -183788,7 +183817,7 @@ async function resolveBlob(ctx, did2, cid2) {
|
|
|
183788
183817
|
if (takenDown) {
|
|
183789
183818
|
throw (0, import_http_errors2.default)(404, "Blob not found");
|
|
183790
183819
|
}
|
|
183791
|
-
const blobResult = await retryHttp(() => getBlob({ pds, did: did2, cid: cidStr }));
|
|
183820
|
+
const blobResult = await retryHttp(() => getBlob(ctx, { pds, did: did2, cid: cidStr }));
|
|
183792
183821
|
const imageStream = blobResult.data;
|
|
183793
183822
|
const verifyCid = new VerifyCidTransform(cid2);
|
|
183794
183823
|
forwardStreamErrors(imageStream, verifyCid);
|
|
@@ -183798,15 +183827,36 @@ async function resolveBlob(ctx, did2, cid2) {
|
|
|
183798
183827
|
stream: imageStream.pipe(verifyCid)
|
|
183799
183828
|
};
|
|
183800
183829
|
}
|
|
183801
|
-
async function getBlob(opts) {
|
|
183830
|
+
async function getBlob(ctx, opts) {
|
|
183802
183831
|
const { pds, did: did2, cid: cid2 } = opts;
|
|
183803
183832
|
return import_axios4.default.get(`${pds}/xrpc/com.atproto.sync.getBlob`, {
|
|
183804
183833
|
params: { did: did2, cid: cid2 },
|
|
183805
183834
|
decompress: true,
|
|
183806
183835
|
responseType: "stream",
|
|
183807
|
-
timeout: 5e3
|
|
183836
|
+
timeout: 5e3,
|
|
183837
|
+
headers: getRateLimitBypassHeaders(ctx, pds)
|
|
183808
183838
|
});
|
|
183809
183839
|
}
|
|
183840
|
+
function getRateLimitBypassHeaders(ctx, pds) {
|
|
183841
|
+
const {
|
|
183842
|
+
blobRateLimitBypassKey: bypassKey,
|
|
183843
|
+
blobRateLimitBypassHostname: bypassHostname
|
|
183844
|
+
} = ctx.cfg;
|
|
183845
|
+
if (!bypassKey || !bypassHostname) {
|
|
183846
|
+
return {};
|
|
183847
|
+
}
|
|
183848
|
+
const url = new URL(pds);
|
|
183849
|
+
if (bypassHostname.startsWith(".")) {
|
|
183850
|
+
if (url.hostname.endsWith(bypassHostname)) {
|
|
183851
|
+
return { "x-ratelimit-bypass": bypassKey };
|
|
183852
|
+
}
|
|
183853
|
+
} else {
|
|
183854
|
+
if (url.hostname === bypassHostname) {
|
|
183855
|
+
return { "x-ratelimit-bypass": bypassKey };
|
|
183856
|
+
}
|
|
183857
|
+
}
|
|
183858
|
+
return {};
|
|
183859
|
+
}
|
|
183810
183860
|
|
|
183811
183861
|
// src/api/index.ts
|
|
183812
183862
|
function api_default(server, ctx) {
|
|
@@ -185527,6 +185577,9 @@ var ServerConfig = class {
|
|
|
185527
185577
|
const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || "2";
|
|
185528
185578
|
const courierIgnoreBadTls = process.env.BSKY_COURIER_IGNORE_BAD_TLS === "true";
|
|
185529
185579
|
(0, import_node_assert3.default)(courierHttpVersion === "1.1" || courierHttpVersion === "2");
|
|
185580
|
+
const blobRateLimitBypassKey = process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || void 0;
|
|
185581
|
+
const blobRateLimitBypassHostname = process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || void 0;
|
|
185582
|
+
(0, import_node_assert3.default)(!blobRateLimitBypassKey || blobRateLimitBypassHostname, "must specify a hostname when using a blob rate limit bypass key");
|
|
185530
185583
|
const adminPasswords = envList(process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD);
|
|
185531
185584
|
const modServiceDid = process.env.MOD_SERVICE_DID;
|
|
185532
185585
|
(0, import_node_assert3.default)(modServiceDid);
|
|
@@ -185555,6 +185608,8 @@ var ServerConfig = class {
|
|
|
185555
185608
|
courierApiKey,
|
|
185556
185609
|
courierHttpVersion,
|
|
185557
185610
|
courierIgnoreBadTls,
|
|
185611
|
+
blobRateLimitBypassKey,
|
|
185612
|
+
blobRateLimitBypassHostname,
|
|
185558
185613
|
adminPasswords,
|
|
185559
185614
|
modServiceDid,
|
|
185560
185615
|
...stripUndefineds(overrides ?? {})
|
|
@@ -185622,6 +185677,12 @@ var ServerConfig = class {
|
|
|
185622
185677
|
get cdnUrl() {
|
|
185623
185678
|
return this.cfg.cdnUrl;
|
|
185624
185679
|
}
|
|
185680
|
+
get blobRateLimitBypassKey() {
|
|
185681
|
+
return this.cfg.blobRateLimitBypassKey;
|
|
185682
|
+
}
|
|
185683
|
+
get blobRateLimitBypassHostname() {
|
|
185684
|
+
return this.cfg.blobRateLimitBypassHostname;
|
|
185685
|
+
}
|
|
185625
185686
|
get didPlcUrl() {
|
|
185626
185687
|
return this.cfg.didPlcUrl;
|
|
185627
185688
|
}
|
|
@@ -186585,7 +186646,7 @@ var BskyAppView = class {
|
|
|
186585
186646
|
});
|
|
186586
186647
|
const authVerifier = new AuthVerifier2(dataplane, {
|
|
186587
186648
|
ownDid: config2.serverDid,
|
|
186588
|
-
|
|
186649
|
+
modServiceDid: config2.modServiceDid,
|
|
186589
186650
|
adminPasses: config2.adminPasswords
|
|
186590
186651
|
});
|
|
186591
186652
|
const ctx = new context_default({
|