@atproto/dev-env 0.3.168 → 0.3.170
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 +26 -0
- package/dist/bin.js +7 -6
- package/dist/bin.js.map +1 -1
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +1 -0
- package/dist/mock/index.js.map +1 -1
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +27 -32
- package/dist/network.js.map +1 -1
- package/dist/service-profile-lexicon.d.ts +11 -0
- package/dist/service-profile-lexicon.d.ts.map +1 -0
- package/dist/service-profile-lexicon.js +96 -0
- package/dist/service-profile-lexicon.js.map +1 -0
- package/dist/service-profile-ozone.d.ts +18 -0
- package/dist/service-profile-ozone.d.ts.map +1 -0
- package/dist/{ozone-service-profile.js → service-profile-ozone.js} +38 -94
- package/dist/service-profile-ozone.js.map +1 -0
- package/dist/service-profile.d.ts +23 -0
- package/dist/service-profile.d.ts.map +1 -0
- package/dist/service-profile.js +80 -0
- package/dist/service-profile.js.map +1 -0
- package/package.json +10 -10
- package/src/bin.ts +7 -8
- package/src/mock/index.ts +1 -0
- package/src/network.ts +34 -37
- package/src/service-profile-lexicon.ts +104 -0
- package/src/{ozone-service-profile.ts → service-profile-ozone.ts} +45 -95
- package/src/service-profile.ts +94 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/ozone-service-profile.d.ts +0 -24
- package/dist/ozone-service-profile.d.ts.map +0 -1
- package/dist/ozone-service-profile.js.map +0 -1
@@ -0,0 +1,23 @@
|
|
1
|
+
import { AtpAgent } from '@atproto/api';
|
2
|
+
import { TestPds } from './pds';
|
3
|
+
export type ServiceUserDetails = {
|
4
|
+
email: string;
|
5
|
+
handle: string;
|
6
|
+
password: string;
|
7
|
+
};
|
8
|
+
export type ServiceMigrationOptions = {
|
9
|
+
services?: Record<string, unknown>;
|
10
|
+
verificationMethods?: Record<string, unknown>;
|
11
|
+
};
|
12
|
+
export declare class ServiceProfile {
|
13
|
+
protected pds: TestPds;
|
14
|
+
/** @note assumes the session is already authenticated */
|
15
|
+
protected client: AtpAgent;
|
16
|
+
protected userDetails: ServiceUserDetails;
|
17
|
+
protected constructor(pds: TestPds,
|
18
|
+
/** @note assumes the session is already authenticated */
|
19
|
+
client: AtpAgent, userDetails: ServiceUserDetails);
|
20
|
+
get did(): string;
|
21
|
+
migrateTo(newPds: TestPds, options?: ServiceMigrationOptions): Promise<void>;
|
22
|
+
}
|
23
|
+
//# sourceMappingURL=service-profile.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"service-profile.d.ts","sourceRoot":"","sources":["../src/service-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9C,CAAA;AAED,qBAAa,cAAc;IAEvB,SAAS,CAAC,GAAG,EAAE,OAAO;IACtB,yDAAyD;IACzD,SAAS,CAAC,MAAM,EAAE,QAAQ;IAC1B,SAAS,CAAC,WAAW,EAAE,kBAAkB;IAJ3C,SAAS,aACG,GAAG,EAAE,OAAO;IACtB,yDAAyD;IAC/C,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,kBAAkB;IAG3C,IAAI,GAAG,WAEN;IAEK,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,uBAA4B;CAmEvE"}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.ServiceProfile = void 0;
|
4
|
+
class ServiceProfile {
|
5
|
+
constructor(pds,
|
6
|
+
/** @note assumes the session is already authenticated */
|
7
|
+
client, userDetails) {
|
8
|
+
Object.defineProperty(this, "pds", {
|
9
|
+
enumerable: true,
|
10
|
+
configurable: true,
|
11
|
+
writable: true,
|
12
|
+
value: pds
|
13
|
+
});
|
14
|
+
Object.defineProperty(this, "client", {
|
15
|
+
enumerable: true,
|
16
|
+
configurable: true,
|
17
|
+
writable: true,
|
18
|
+
value: client
|
19
|
+
});
|
20
|
+
Object.defineProperty(this, "userDetails", {
|
21
|
+
enumerable: true,
|
22
|
+
configurable: true,
|
23
|
+
writable: true,
|
24
|
+
value: userDetails
|
25
|
+
});
|
26
|
+
}
|
27
|
+
get did() {
|
28
|
+
return this.client.assertDid;
|
29
|
+
}
|
30
|
+
async migrateTo(newPds, options = {}) {
|
31
|
+
const newClient = newPds.getClient();
|
32
|
+
const newPdsDesc = await newClient.com.atproto.server.describeServer();
|
33
|
+
const serviceAuth = await this.client.com.atproto.server.getServiceAuth({
|
34
|
+
aud: newPdsDesc.data.did,
|
35
|
+
lxm: 'com.atproto.server.createAccount',
|
36
|
+
});
|
37
|
+
const inviteCode = newPds.ctx.cfg.invites.required
|
38
|
+
? await newClient.com.atproto.server
|
39
|
+
.createInviteCode({ useCount: 1 }, {
|
40
|
+
encoding: 'application/json',
|
41
|
+
headers: newPds.adminAuthHeaders(),
|
42
|
+
})
|
43
|
+
.then((res) => res.data.code)
|
44
|
+
: undefined;
|
45
|
+
await newClient.createAccount({
|
46
|
+
...this.userDetails,
|
47
|
+
inviteCode,
|
48
|
+
did: this.did,
|
49
|
+
}, {
|
50
|
+
encoding: 'application/json',
|
51
|
+
headers: { authorization: `Bearer ${serviceAuth.data.token}` },
|
52
|
+
});
|
53
|
+
// The session manager will use the "didDoc" in the result of
|
54
|
+
// "createAccount" in order to setup the pdsUrl. However, since are in the
|
55
|
+
// process of migrating, that didDoc references the old PDS. In order to
|
56
|
+
// avoid calling the old PDS, let's clear the pdsUrl, which will result in
|
57
|
+
// the (new) serviceUrl being used.
|
58
|
+
newClient.sessionManager.pdsUrl = undefined;
|
59
|
+
const newDidCredentialsRes = await newClient.com.atproto.identity.getRecommendedDidCredentials();
|
60
|
+
await this.client.com.atproto.identity.requestPlcOperationSignature();
|
61
|
+
const { token } = await this.pds.ctx.accountManager.db.db
|
62
|
+
.selectFrom('email_token')
|
63
|
+
.select('token')
|
64
|
+
.where('did', '=', this.did)
|
65
|
+
.where('purpose', '=', 'plc_operation')
|
66
|
+
.executeTakeFirstOrThrow();
|
67
|
+
const op = { ...newDidCredentialsRes.data, token };
|
68
|
+
Object.assign((op.services ?? (op.services = {})), options.services);
|
69
|
+
Object.assign((op.verificationMethods ?? (op.verificationMethods = {})), options.verificationMethods);
|
70
|
+
const signedPlcOperation = await this.client.com.atproto.identity.signPlcOperation(op);
|
71
|
+
await newClient.com.atproto.identity.submitPlcOperation({
|
72
|
+
operation: signedPlcOperation.data.operation,
|
73
|
+
});
|
74
|
+
await newClient.com.atproto.server.activateAccount();
|
75
|
+
this.pds = newPds;
|
76
|
+
this.client = newClient;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
exports.ServiceProfile = ServiceProfile;
|
80
|
+
//# sourceMappingURL=service-profile.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"service-profile.js","sourceRoot":"","sources":["../src/service-profile.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@atproto/dev-env",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.170",
|
4
4
|
"license": "MIT",
|
5
5
|
"description": "Local development environment helper for atproto development",
|
6
6
|
"keywords": [
|
@@ -27,18 +27,18 @@
|
|
27
27
|
"multiformats": "^9.9.0",
|
28
28
|
"uint8arrays": "3.0.0",
|
29
29
|
"undici": "^6.14.1",
|
30
|
-
"@atproto/api": "^0.16.
|
31
|
-
"@atproto/bsky": "^0.0.
|
32
|
-
"@atproto/bsync": "^0.0.
|
30
|
+
"@atproto/api": "^0.16.6",
|
31
|
+
"@atproto/bsky": "^0.0.181",
|
32
|
+
"@atproto/bsync": "^0.0.21",
|
33
33
|
"@atproto/common-web": "^0.4.2",
|
34
34
|
"@atproto/crypto": "^0.4.4",
|
35
35
|
"@atproto/identity": "^0.4.8",
|
36
|
-
"@atproto/lexicon": "^0.
|
37
|
-
"@atproto/ozone": "^0.1.
|
38
|
-
"@atproto/pds": "^0.4.
|
39
|
-
"@atproto/sync": "^0.1.
|
40
|
-
"@atproto/syntax": "^0.4.
|
41
|
-
"@atproto/xrpc-server": "^0.9.
|
36
|
+
"@atproto/lexicon": "^0.5.0",
|
37
|
+
"@atproto/ozone": "^0.1.139",
|
38
|
+
"@atproto/pds": "^0.4.174",
|
39
|
+
"@atproto/sync": "^0.1.33",
|
40
|
+
"@atproto/syntax": "^0.4.1",
|
41
|
+
"@atproto/xrpc-server": "^0.9.4"
|
42
42
|
},
|
43
43
|
"devDependencies": {
|
44
44
|
"@types/express": "^4.17.13",
|
package/src/bin.ts
CHANGED
@@ -39,21 +39,20 @@ const run = async () => {
|
|
39
39
|
|
40
40
|
if (network.introspect) {
|
41
41
|
console.log(
|
42
|
-
`🔍 Dev-env introspection server
|
42
|
+
`🔍 Dev-env introspection server http://localhost:${network.introspect.port}`,
|
43
43
|
)
|
44
44
|
}
|
45
|
+
console.log(`👤 DID Placeholder server http://localhost:${network.plc.port}`)
|
46
|
+
console.log(`🌞 Main PDS http://localhost:${network.pds.port}`)
|
45
47
|
console.log(
|
46
|
-
|
48
|
+
`🔨 Lexicon authority DID ${network.pds.ctx.cfg.lexicon.didAuthority}`,
|
47
49
|
)
|
48
|
-
console.log(
|
49
|
-
`🌞 Personal Data server started http://localhost:${network.pds.port}`,
|
50
|
-
)
|
51
|
-
console.log(`🗼 Ozone server started http://localhost:${network.ozone.port}`)
|
50
|
+
console.log(`🗼 Ozone server http://localhost:${network.ozone.port}`)
|
52
51
|
console.log(`🗼 Ozone service DID ${network.ozone.ctx.cfg.service.did}`)
|
53
|
-
console.log(`🌅 Bsky Appview
|
52
|
+
console.log(`🌅 Bsky Appview http://localhost:${network.bsky.port}`)
|
54
53
|
console.log(`🌅 Bsky Appview DID ${network.bsky.serverDid}`)
|
55
54
|
for (const fg of network.feedGens) {
|
56
|
-
console.log(`🤖 Feed Generator
|
55
|
+
console.log(`🤖 Feed Generator (${fg.did}) http://localhost:${fg.port}`)
|
57
56
|
}
|
58
57
|
}
|
59
58
|
|
package/src/mock/index.ts
CHANGED
@@ -542,6 +542,7 @@ export async function generateMockSetup(env: TestNetwork) {
|
|
542
542
|
|
543
543
|
await setVerifier(env.bsky.db, alice.accountDid)
|
544
544
|
|
545
|
+
// @TODO the following should be optimized as it makes dev-env start very slow (>10 sec)
|
545
546
|
const sc = env.getSeedClient()
|
546
547
|
await seedThreadV2.simple(sc)
|
547
548
|
await seedThreadV2.long(sc)
|
package/src/network.ts
CHANGED
@@ -8,9 +8,10 @@ import { EXAMPLE_LABELER } from './const'
|
|
8
8
|
import { IntrospectServer } from './introspect'
|
9
9
|
import { TestNetworkNoAppView } from './network-no-appview'
|
10
10
|
import { TestOzone } from './ozone'
|
11
|
-
import { OzoneServiceProfile } from './ozone-service-profile'
|
12
11
|
import { TestPds } from './pds'
|
13
12
|
import { TestPlc } from './plc'
|
13
|
+
import { LexiconAuthorityProfile } from './service-profile-lexicon'
|
14
|
+
import { OzoneServiceProfile } from './service-profile-ozone'
|
14
15
|
import { TestServerParams } from './types'
|
15
16
|
import { mockNetworkUtilities } from './util'
|
16
17
|
|
@@ -44,16 +45,23 @@ export class TestNetwork extends TestNetworkNoAppView {
|
|
44
45
|
const pdsPort = params.pds?.port ?? (await getPort())
|
45
46
|
const ozonePort = params.ozone?.port ?? (await getPort())
|
46
47
|
|
47
|
-
const
|
48
|
+
const thirdPartyPds = await TestPds.create({
|
48
49
|
didPlcUrl: plc.url,
|
49
50
|
...params.pds,
|
50
51
|
inviteRequired: false,
|
51
52
|
port: await getPort(),
|
52
|
-
}
|
53
|
-
|
54
|
-
const
|
55
|
-
|
56
|
-
|
53
|
+
})
|
54
|
+
|
55
|
+
const ozoneUrl = `http://localhost:${ozonePort}`
|
56
|
+
|
57
|
+
// @TODO (?) rework the ServiceProfile to live on a separate PDS instead of
|
58
|
+
// requiring to migrate to the main PDS
|
59
|
+
const ozoneServiceProfile = await OzoneServiceProfile.create(
|
60
|
+
thirdPartyPds,
|
61
|
+
ozoneUrl,
|
62
|
+
)
|
63
|
+
const lexiconAuthorityProfile =
|
64
|
+
await LexiconAuthorityProfile.create(thirdPartyPds)
|
57
65
|
|
58
66
|
const bsky = await TestBsky.create({
|
59
67
|
port: bskyPort,
|
@@ -63,29 +71,27 @@ export class TestNetwork extends TestNetworkNoAppView {
|
|
63
71
|
dbPostgresSchema: `appview_${dbPostgresSchema}`,
|
64
72
|
dbPostgresUrl,
|
65
73
|
redisHost,
|
66
|
-
modServiceDid:
|
67
|
-
labelsFromIssuerDids: [
|
74
|
+
modServiceDid: ozoneServiceProfile.did,
|
75
|
+
labelsFromIssuerDids: [ozoneServiceProfile.did, EXAMPLE_LABELER],
|
68
76
|
...params.bsky,
|
69
77
|
})
|
70
78
|
|
71
|
-
const
|
72
|
-
const pdsProps = {
|
79
|
+
const pds = await TestPds.create({
|
73
80
|
port: pdsPort,
|
74
81
|
didPlcUrl: plc.url,
|
75
82
|
bskyAppViewUrl: bsky.url,
|
76
83
|
bskyAppViewDid: bsky.ctx.cfg.serverDid,
|
77
|
-
modServiceUrl,
|
78
|
-
modServiceDid:
|
84
|
+
modServiceUrl: ozoneUrl,
|
85
|
+
modServiceDid: ozoneServiceProfile.did,
|
86
|
+
lexiconDidAuthority: lexiconAuthorityProfile.did,
|
79
87
|
...params.pds,
|
80
|
-
}
|
81
|
-
|
82
|
-
const pds = await TestPds.create(pdsProps)
|
88
|
+
})
|
83
89
|
|
84
90
|
const ozone = await TestOzone.create({
|
85
91
|
port: ozonePort,
|
86
92
|
plcUrl: plc.url,
|
87
|
-
signingKey:
|
88
|
-
serverDid:
|
93
|
+
signingKey: ozoneServiceProfile.key,
|
94
|
+
serverDid: ozoneServiceProfile.did,
|
89
95
|
dbPostgresSchema: `ozone_${dbPostgresSchema || 'db'}`,
|
90
96
|
dbPostgresUrl,
|
91
97
|
appviewUrl: bsky.url,
|
@@ -93,39 +99,30 @@ export class TestNetwork extends TestNetworkNoAppView {
|
|
93
99
|
appviewPushEvents: true,
|
94
100
|
pdsUrl: pds.url,
|
95
101
|
pdsDid: pds.ctx.cfg.service.did,
|
96
|
-
verifierDid:
|
102
|
+
verifierDid: ozoneServiceProfile.did,
|
97
103
|
verifierUrl: pds.url,
|
98
104
|
verifierPassword: 'temp',
|
99
105
|
...params.ozone,
|
100
106
|
})
|
101
107
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
{ useCount: 1 },
|
108
|
-
{
|
109
|
-
encoding: 'application/json',
|
110
|
-
headers: pds.adminAuthHeaders(),
|
111
|
-
},
|
112
|
-
)
|
113
|
-
inviteCode = invite.code
|
114
|
-
}
|
115
|
-
await ozoneServiceProfile.createServiceDetails(pds, modServiceUrl, {
|
116
|
-
inviteCode,
|
117
|
-
})
|
108
|
+
await ozoneServiceProfile.migrateTo(pds)
|
109
|
+
await ozoneServiceProfile.createRecords()
|
110
|
+
|
111
|
+
await lexiconAuthorityProfile.migrateTo(pds)
|
112
|
+
await lexiconAuthorityProfile.createRecords()
|
118
113
|
|
119
|
-
await ozone.addAdminDid(
|
114
|
+
await ozone.addAdminDid(ozoneServiceProfile.did)
|
120
115
|
|
121
116
|
mockNetworkUtilities(pds, bsky)
|
117
|
+
await thirdPartyPds.processAll()
|
122
118
|
await pds.processAll()
|
119
|
+
await ozone.processAll()
|
123
120
|
await bsky.sub.processAll()
|
124
121
|
await thirdPartyPds.close()
|
125
122
|
|
126
123
|
// Weird but if we do this before pds.processAll() somehow appview loses this user and tests in different parts fail because appview doesn't return this user in various contexts anymore
|
127
124
|
const ozoneVerifierPassword =
|
128
|
-
await ozoneServiceProfile.createAppPasswordForVerification(
|
125
|
+
await ozoneServiceProfile.createAppPasswordForVerification()
|
129
126
|
if (ozone.daemon.ctx.cfg.verifier) {
|
130
127
|
ozone.daemon.ctx.cfg.verifier.password = ozoneVerifierPassword
|
131
128
|
}
|
@@ -0,0 +1,104 @@
|
|
1
|
+
import { LexiconDoc } from '@atproto/lexicon'
|
2
|
+
import { TestPds } from './pds'
|
3
|
+
import { ServiceProfile } from './service-profile'
|
4
|
+
|
5
|
+
const LEXICONS: readonly LexiconDoc[] = [
|
6
|
+
{
|
7
|
+
lexicon: 1,
|
8
|
+
id: 'com.atproto.moderation.basePermissions',
|
9
|
+
defs: {
|
10
|
+
main: {
|
11
|
+
type: 'permission-set',
|
12
|
+
title: 'Moderation',
|
13
|
+
'title:lang': { fr: 'Modération' },
|
14
|
+
detail: 'Create moderation reports',
|
15
|
+
'detail:lang': {
|
16
|
+
'fr-FR': 'Créer des rapports de modération',
|
17
|
+
},
|
18
|
+
permissions: [
|
19
|
+
{
|
20
|
+
type: 'permission',
|
21
|
+
resource: 'rpc',
|
22
|
+
aud: '*',
|
23
|
+
lxm: ['com.atproto.moderation.createReport'],
|
24
|
+
},
|
25
|
+
],
|
26
|
+
},
|
27
|
+
},
|
28
|
+
},
|
29
|
+
{
|
30
|
+
lexicon: 1,
|
31
|
+
id: 'com.example.calendar.basePermissions',
|
32
|
+
defs: {
|
33
|
+
main: {
|
34
|
+
type: 'permission-set',
|
35
|
+
title: 'Calendar',
|
36
|
+
'title:lang': { fr: 'Calendrier' },
|
37
|
+
detail: 'Manage your events and RSVPs',
|
38
|
+
'detail:lang': {
|
39
|
+
'fr-BE': 'Gérer vos événements et réponses',
|
40
|
+
},
|
41
|
+
permissions: [
|
42
|
+
{
|
43
|
+
type: 'permission',
|
44
|
+
resource: 'rpc',
|
45
|
+
inheritAud: true,
|
46
|
+
lxm: [
|
47
|
+
'com.example.calendar.listEvents',
|
48
|
+
'com.example.calendar.getEventDetails',
|
49
|
+
'com.example.calendar.getEventRsvps',
|
50
|
+
],
|
51
|
+
},
|
52
|
+
{
|
53
|
+
type: 'permission',
|
54
|
+
resource: 'repo',
|
55
|
+
collection: [
|
56
|
+
'com.example.calendar.event',
|
57
|
+
'com.example.calendar.rsvp',
|
58
|
+
],
|
59
|
+
},
|
60
|
+
{
|
61
|
+
type: 'permission',
|
62
|
+
resource: 'blob',
|
63
|
+
accept: ['image/*', 'video/*'],
|
64
|
+
},
|
65
|
+
],
|
66
|
+
},
|
67
|
+
},
|
68
|
+
},
|
69
|
+
]
|
70
|
+
|
71
|
+
export class LexiconAuthorityProfile extends ServiceProfile {
|
72
|
+
public static async create(
|
73
|
+
pds: TestPds,
|
74
|
+
userDetails = {
|
75
|
+
email: 'lex-authority@test.com',
|
76
|
+
handle: 'lex-authority.test',
|
77
|
+
password: 'hunter2',
|
78
|
+
},
|
79
|
+
) {
|
80
|
+
const client = pds.getClient()
|
81
|
+
await client.createAccount(userDetails)
|
82
|
+
|
83
|
+
return new LexiconAuthorityProfile(pds, client, userDetails)
|
84
|
+
}
|
85
|
+
|
86
|
+
async createRecords() {
|
87
|
+
await this.client.app.bsky.actor.profile.create(
|
88
|
+
{ repo: this.did },
|
89
|
+
{
|
90
|
+
displayName: 'Lexicon Authority',
|
91
|
+
description: `the repo containing all the lexicons that can be resolved in dev`,
|
92
|
+
},
|
93
|
+
)
|
94
|
+
|
95
|
+
for (const doc of LEXICONS) {
|
96
|
+
await this.client.com.atproto.repo.createRecord({
|
97
|
+
repo: this.did,
|
98
|
+
collection: 'com.atproto.lexicon.schema',
|
99
|
+
rkey: doc.id,
|
100
|
+
record: doc,
|
101
|
+
})
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
@@ -1,116 +1,66 @@
|
|
1
1
|
import { AtpAgent } from '@atproto/api'
|
2
2
|
import { Secp256k1Keypair } from '@atproto/crypto'
|
3
3
|
import { TestPds } from './pds'
|
4
|
+
import {
|
5
|
+
ServiceMigrationOptions,
|
6
|
+
ServiceProfile,
|
7
|
+
ServiceUserDetails,
|
8
|
+
} from './service-profile'
|
4
9
|
|
5
|
-
export class OzoneServiceProfile {
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
export class OzoneServiceProfile extends ServiceProfile {
|
11
|
+
static async create(
|
12
|
+
pds: TestPds,
|
13
|
+
ozoneUrl: string,
|
14
|
+
userDetails = {
|
15
|
+
email: 'mod-authority@test.com',
|
16
|
+
handle: 'mod-authority.test',
|
17
|
+
password: 'hunter2',
|
18
|
+
},
|
19
|
+
) {
|
20
|
+
const client = pds.getClient()
|
21
|
+
await client.createAccount(userDetails)
|
9
22
|
|
10
|
-
|
11
|
-
email: 'mod-authority@test.com',
|
12
|
-
handle: 'mod-authority.test',
|
13
|
-
password: 'hunter2',
|
14
|
-
}
|
23
|
+
const key = await Secp256k1Keypair.create({ exportable: true })
|
15
24
|
|
16
|
-
|
17
|
-
this.thirdPartyPdsClient = this.thirdPartyPds.getClient()
|
25
|
+
return new OzoneServiceProfile(pds, client, userDetails, ozoneUrl, key)
|
18
26
|
}
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
protected constructor(
|
29
|
+
pds: TestPds,
|
30
|
+
client: AtpAgent,
|
31
|
+
userDetails: ServiceUserDetails,
|
32
|
+
readonly ozoneUrl: string,
|
33
|
+
readonly key: Secp256k1Keypair,
|
34
|
+
) {
|
35
|
+
super(pds, client, userDetails)
|
26
36
|
}
|
27
37
|
|
28
|
-
async createAppPasswordForVerification(
|
29
|
-
const
|
30
|
-
await pdsClient.login({
|
31
|
-
identifier: this.modUserDetails.handle,
|
32
|
-
password: this.modUserDetails.password,
|
33
|
-
})
|
34
|
-
const { data } = await pdsClient.com.atproto.server.createAppPassword({
|
38
|
+
async createAppPasswordForVerification() {
|
39
|
+
const { data } = await this.client.com.atproto.server.createAppPassword({
|
35
40
|
name: 'ozone-verifier',
|
36
41
|
})
|
37
42
|
return data.password
|
38
43
|
}
|
39
44
|
|
40
|
-
async
|
41
|
-
pds
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
const describeRes = await pdsClient.com.atproto.server.describeServer()
|
50
|
-
const newServerDid = describeRes.data.did
|
51
|
-
|
52
|
-
const serviceJwtRes =
|
53
|
-
await this.thirdPartyPdsClient.com.atproto.server.getServiceAuth({
|
54
|
-
aud: newServerDid,
|
55
|
-
lxm: 'com.atproto.server.createAccount',
|
56
|
-
})
|
57
|
-
const serviceJwt = serviceJwtRes.data.token
|
58
|
-
|
59
|
-
await pdsClient.createAccount(
|
60
|
-
{
|
61
|
-
...this.modUserDetails,
|
62
|
-
...userDetails,
|
63
|
-
did: this.did,
|
45
|
+
async migrateTo(pds: TestPds, options: ServiceMigrationOptions = {}) {
|
46
|
+
await super.migrateTo(pds, {
|
47
|
+
...options,
|
48
|
+
services: {
|
49
|
+
...options.services,
|
50
|
+
atproto_labeler: {
|
51
|
+
type: 'AtprotoLabeler',
|
52
|
+
endpoint: this.ozoneUrl,
|
53
|
+
},
|
64
54
|
},
|
65
|
-
{
|
66
|
-
|
67
|
-
|
55
|
+
verificationMethods: {
|
56
|
+
...options.verificationMethods,
|
57
|
+
atproto_label: this.key.did(),
|
68
58
|
},
|
69
|
-
)
|
70
|
-
|
71
|
-
// For some reason, the tests fail if the client uses the PDS URL to make
|
72
|
-
// its requests. This is a workaround to make the tests pass by simulating
|
73
|
-
// old behavior (that was not relying on the session management).
|
74
|
-
pdsClient.sessionManager.pdsUrl = undefined
|
75
|
-
|
76
|
-
const getDidCredentials =
|
77
|
-
await pdsClient.com.atproto.identity.getRecommendedDidCredentials()
|
78
|
-
|
79
|
-
await this.thirdPartyPdsClient.com.atproto.identity.requestPlcOperationSignature()
|
80
|
-
|
81
|
-
const tokenRes = await this.thirdPartyPds.ctx.accountManager.db.db
|
82
|
-
.selectFrom('email_token')
|
83
|
-
.selectAll()
|
84
|
-
.where('did', '=', this.did)
|
85
|
-
.where('purpose', '=', 'plc_operation')
|
86
|
-
.executeTakeFirst()
|
87
|
-
const token = tokenRes?.token
|
88
|
-
const plcOperationData = {
|
89
|
-
token,
|
90
|
-
...getDidCredentials.data,
|
91
|
-
}
|
92
|
-
|
93
|
-
if (!plcOperationData.services) plcOperationData.services = {}
|
94
|
-
plcOperationData.services['atproto_labeler'] = {
|
95
|
-
type: 'AtprotoLabeler',
|
96
|
-
endpoint: ozoneUrl,
|
97
|
-
}
|
98
|
-
if (!plcOperationData.verificationMethods)
|
99
|
-
plcOperationData.verificationMethods = {}
|
100
|
-
plcOperationData.verificationMethods['atproto_label'] = this.key.did()
|
101
|
-
|
102
|
-
const plcOp =
|
103
|
-
await this.thirdPartyPdsClient.com.atproto.identity.signPlcOperation(
|
104
|
-
plcOperationData,
|
105
|
-
)
|
106
|
-
|
107
|
-
await pdsClient.com.atproto.identity.submitPlcOperation({
|
108
|
-
operation: plcOp.data.operation,
|
109
59
|
})
|
60
|
+
}
|
110
61
|
|
111
|
-
|
112
|
-
|
113
|
-
await pdsClient.app.bsky.actor.profile.create(
|
62
|
+
async createRecords() {
|
63
|
+
await this.client.app.bsky.actor.profile.create(
|
114
64
|
{ repo: this.did },
|
115
65
|
{
|
116
66
|
displayName: 'Dev-env Moderation',
|
@@ -118,7 +68,7 @@ export class OzoneServiceProfile {
|
|
118
68
|
},
|
119
69
|
)
|
120
70
|
|
121
|
-
await
|
71
|
+
await this.client.app.bsky.labeler.service.create(
|
122
72
|
{ repo: this.did, rkey: 'self' },
|
123
73
|
{
|
124
74
|
policies: {
|