@atproto/pds 0.4.0 → 0.4.1

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.
@@ -20,6 +20,7 @@ import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRep
20
20
  import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail';
21
21
  import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail';
22
22
  import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle';
23
+ import * as ComAtprotoAdminUpdateAccountPassword from './types/com/atproto/admin/updateAccountPassword';
23
24
  import * as ComAtprotoAdminUpdateCommunicationTemplate from './types/com/atproto/admin/updateCommunicationTemplate';
24
25
  import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus';
25
26
  import * as ComAtprotoIdentityGetRecommendedDidCredentials from './types/com/atproto/identity/getRecommendedDidCredentials';
@@ -192,6 +193,7 @@ export declare class ComAtprotoAdminNS {
192
193
  sendEmail<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminSendEmail.Handler<ExtractAuth<AV>>, ComAtprotoAdminSendEmail.HandlerReqCtx<ExtractAuth<AV>>>): void;
193
194
  updateAccountEmail<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminUpdateAccountEmail.Handler<ExtractAuth<AV>>, ComAtprotoAdminUpdateAccountEmail.HandlerReqCtx<ExtractAuth<AV>>>): void;
194
195
  updateAccountHandle<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminUpdateAccountHandle.Handler<ExtractAuth<AV>>, ComAtprotoAdminUpdateAccountHandle.HandlerReqCtx<ExtractAuth<AV>>>): void;
196
+ updateAccountPassword<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminUpdateAccountPassword.Handler<ExtractAuth<AV>>, ComAtprotoAdminUpdateAccountPassword.HandlerReqCtx<ExtractAuth<AV>>>): void;
195
197
  updateCommunicationTemplate<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminUpdateCommunicationTemplate.Handler<ExtractAuth<AV>>, ComAtprotoAdminUpdateCommunicationTemplate.HandlerReqCtx<ExtractAuth<AV>>>): void;
196
198
  updateSubjectStatus<AV extends AuthVerifier>(cfg: ConfigOf<AV, ComAtprotoAdminUpdateSubjectStatus.Handler<ExtractAuth<AV>>, ComAtprotoAdminUpdateSubjectStatus.HandlerReqCtx<ExtractAuth<AV>>>): void;
197
199
  }
@@ -1695,6 +1695,32 @@ export declare const schemaDict: {
1695
1695
  };
1696
1696
  };
1697
1697
  };
1698
+ ComAtprotoAdminUpdateAccountPassword: {
1699
+ lexicon: number;
1700
+ id: string;
1701
+ defs: {
1702
+ main: {
1703
+ type: string;
1704
+ description: string;
1705
+ input: {
1706
+ encoding: string;
1707
+ schema: {
1708
+ type: string;
1709
+ required: string[];
1710
+ properties: {
1711
+ did: {
1712
+ type: string;
1713
+ format: string;
1714
+ };
1715
+ password: {
1716
+ type: string;
1717
+ };
1718
+ };
1719
+ };
1720
+ };
1721
+ };
1722
+ };
1723
+ };
1698
1724
  ComAtprotoAdminUpdateCommunicationTemplate: {
1699
1725
  lexicon: number;
1700
1726
  id: string;
@@ -8205,6 +8231,7 @@ export declare const ids: {
8205
8231
  ComAtprotoAdminSendEmail: string;
8206
8232
  ComAtprotoAdminUpdateAccountEmail: string;
8207
8233
  ComAtprotoAdminUpdateAccountHandle: string;
8234
+ ComAtprotoAdminUpdateAccountPassword: string;
8208
8235
  ComAtprotoAdminUpdateCommunicationTemplate: string;
8209
8236
  ComAtprotoAdminUpdateSubjectStatus: string;
8210
8237
  ComAtprotoIdentityGetRecommendedDidCredentials: string;
@@ -54,7 +54,7 @@ export interface ViewerState {
54
54
  }
55
55
  export declare function isViewerState(v: unknown): v is ViewerState;
56
56
  export declare function validateViewerState(v: unknown): ValidationResult;
57
- export type Preferences = (AdultContentPref | ContentLabelPref | SavedFeedsPref | PersonalDetailsPref | FeedViewPref | ThreadViewPref | InterestsPref | {
57
+ export type Preferences = (AdultContentPref | ContentLabelPref | SavedFeedsPref | PersonalDetailsPref | FeedViewPref | ThreadViewPref | InterestsPref | MutedWordsPref | HiddenPostsPref | {
58
58
  $type: string;
59
59
  [k: string]: unknown;
60
60
  })[];
@@ -0,0 +1,26 @@
1
+ import express from 'express';
2
+ import { HandlerAuth } from '@atproto/xrpc-server';
3
+ export interface QueryParams {
4
+ }
5
+ export interface InputSchema {
6
+ did: string;
7
+ password: string;
8
+ [k: string]: unknown;
9
+ }
10
+ export interface HandlerInput {
11
+ encoding: 'application/json';
12
+ body: InputSchema;
13
+ }
14
+ export interface HandlerError {
15
+ status: number;
16
+ message?: string;
17
+ }
18
+ export type HandlerOutput = HandlerError | void;
19
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
20
+ auth: HA;
21
+ params: QueryParams;
22
+ input: HandlerInput;
23
+ req: express.Request;
24
+ res: express.Response;
25
+ };
26
+ export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/pds",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of atproto Personal Data Server (PDS)",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  "typed-emitter": "^2.1.0",
45
45
  "uint8arrays": "3.0.0",
46
46
  "zod": "^3.21.4",
47
- "@atproto/api": "^0.10.0",
47
+ "@atproto/api": "^0.10.1",
48
48
  "@atproto/aws": "^0.1.7",
49
49
  "@atproto/common": "^0.3.3",
50
50
  "@atproto/crypto": "^0.3.0",
@@ -68,9 +68,9 @@
68
68
  "axios": "^0.27.2",
69
69
  "get-port": "^6.1.2",
70
70
  "ws": "^8.12.0",
71
- "@atproto/api": "^0.10.0",
72
- "@atproto/bsky": "^0.0.32",
73
- "@atproto/dev-env": "^0.2.32",
71
+ "@atproto/api": "^0.10.1",
72
+ "@atproto/bsky": "^0.0.33",
73
+ "@atproto/dev-env": "^0.2.33",
74
74
  "@atproto/lex-cli": "^0.3.0"
75
75
  },
76
76
  "scripts": {
@@ -370,6 +370,11 @@ export class AccountManager {
370
370
  'reset_password',
371
371
  opts.token,
372
372
  )
373
+ await this.updateAccountPassword({ did, password: opts.password })
374
+ }
375
+
376
+ async updateAccountPassword(opts: { did: string; password: string }) {
377
+ const { did } = opts
373
378
  const passwordScrypt = await scrypt.genSaltAndHash(opts.password)
374
379
  await this.db.transaction(async (dbTxn) =>
375
380
  Promise.all([
@@ -15,6 +15,7 @@ import disableInviteCodes from './disableInviteCodes'
15
15
  import getInviteCodes from './getInviteCodes'
16
16
  import updateAccountHandle from './updateAccountHandle'
17
17
  import updateAccountEmail from './updateAccountEmail'
18
+ import updateAccountPassword from './updateAccountPassword'
18
19
  import sendEmail from './sendEmail'
19
20
  import deleteAccount from './deleteAccount'
20
21
  import queryModerationStatuses from './queryModerationStatuses'
@@ -40,6 +41,7 @@ export default function (server: Server, ctx: AppContext) {
40
41
  getInviteCodes(server, ctx)
41
42
  updateAccountHandle(server, ctx)
42
43
  updateAccountEmail(server, ctx)
44
+ updateAccountPassword(server, ctx)
43
45
  sendEmail(server, ctx)
44
46
  deleteAccount(server, ctx)
45
47
  listCommunicationTemplates(server, ctx)
@@ -0,0 +1,28 @@
1
+ import { AuthRequiredError } from '@atproto/xrpc-server'
2
+ import { Server } from '../../../../lexicon'
3
+ import AppContext from '../../../../context'
4
+ import { authPassthru } from '../../../proxy'
5
+
6
+ export default function (server: Server, ctx: AppContext) {
7
+ server.com.atproto.admin.updateAccountPassword({
8
+ auth: ctx.authVerifier.role,
9
+ handler: async ({ input, auth, req }) => {
10
+ if (!auth.credentials.admin) {
11
+ throw new AuthRequiredError(
12
+ 'Must be an admin to update an account password',
13
+ )
14
+ }
15
+
16
+ if (ctx.entrywayAgent) {
17
+ await ctx.entrywayAgent.com.atproto.admin.updateAccountPassword(
18
+ input.body,
19
+ authPassthru(req, true),
20
+ )
21
+ return
22
+ }
23
+
24
+ const { did, password } = input.body
25
+ await ctx.accountManager.updateAccountPassword({ did, password })
26
+ },
27
+ })
28
+ }
@@ -23,6 +23,7 @@ export const envToCfg = (env: ServerEnvironment): ServerConfig => {
23
23
  privacyPolicyUrl: env.privacyPolicyUrl,
24
24
  termsOfServiceUrl: env.termsOfServiceUrl,
25
25
  acceptingImports: env.acceptingImports ?? true,
26
+ blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024, // 5mb
26
27
  }
27
28
 
28
29
  const dbLoc = (name: string) => {
@@ -275,9 +276,10 @@ export type ServiceConfig = {
275
276
  publicUrl: string
276
277
  did: string
277
278
  version?: string
278
- acceptingImports: boolean
279
279
  privacyPolicyUrl?: string
280
280
  termsOfServiceUrl?: string
281
+ acceptingImports: boolean
282
+ blobUploadLimit: number
281
283
  }
282
284
 
283
285
  export type DatabaseConfig = {
package/src/config/env.ts CHANGED
@@ -10,6 +10,7 @@ export const readEnv = (): ServerEnvironment => {
10
10
  privacyPolicyUrl: envStr('PDS_PRIVACY_POLICY_URL'),
11
11
  termsOfServiceUrl: envStr('PDS_TERMS_OF_SERVICE_URL'),
12
12
  acceptingImports: envBool('PDS_ACCEPTING_REPO_IMPORTS'),
13
+ blobUploadLimit: envInt('PDS_BLOB_UPLOAD_LIMIT'),
13
14
 
14
15
  // database
15
16
  dataDirectory: envStr('PDS_DATA_DIRECTORY'),
@@ -116,6 +117,7 @@ export type ServerEnvironment = {
116
117
  privacyPolicyUrl?: string
117
118
  termsOfServiceUrl?: string
118
119
  acceptingImports?: boolean
120
+ blobUploadLimit?: number
119
121
 
120
122
  // database
121
123
  dataDirectory?: string
package/src/index.ts CHANGED
@@ -63,7 +63,7 @@ export class PDS {
63
63
  payload: {
64
64
  jsonLimit: 100 * 1024, // 100kb
65
65
  textLimit: 100 * 1024, // 100kb
66
- blobLimit: 5 * 1024 * 1024, // 5mb
66
+ blobLimit: cfg.service.blobUploadLimit,
67
67
  },
68
68
  }
69
69
  if (cfg.rateLimits.enabled) {
@@ -30,6 +30,7 @@ import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRep
30
30
  import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail'
31
31
  import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail'
32
32
  import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle'
33
+ import * as ComAtprotoAdminUpdateAccountPassword from './types/com/atproto/admin/updateAccountPassword'
33
34
  import * as ComAtprotoAdminUpdateCommunicationTemplate from './types/com/atproto/admin/updateCommunicationTemplate'
34
35
  import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus'
35
36
  import * as ComAtprotoIdentityGetRecommendedDidCredentials from './types/com/atproto/identity/getRecommendedDidCredentials'
@@ -444,6 +445,17 @@ export class ComAtprotoAdminNS {
444
445
  return this._server.xrpc.method(nsid, cfg)
445
446
  }
446
447
 
448
+ updateAccountPassword<AV extends AuthVerifier>(
449
+ cfg: ConfigOf<
450
+ AV,
451
+ ComAtprotoAdminUpdateAccountPassword.Handler<ExtractAuth<AV>>,
452
+ ComAtprotoAdminUpdateAccountPassword.HandlerReqCtx<ExtractAuth<AV>>
453
+ >,
454
+ ) {
455
+ const nsid = 'com.atproto.admin.updateAccountPassword' // @ts-ignore
456
+ return this._server.xrpc.method(nsid, cfg)
457
+ }
458
+
447
459
  updateCommunicationTemplate<AV extends AuthVerifier>(
448
460
  cfg: ConfigOf<
449
461
  AV,
@@ -1863,6 +1863,33 @@ export const schemaDict = {
1863
1863
  },
1864
1864
  },
1865
1865
  },
1866
+ ComAtprotoAdminUpdateAccountPassword: {
1867
+ lexicon: 1,
1868
+ id: 'com.atproto.admin.updateAccountPassword',
1869
+ defs: {
1870
+ main: {
1871
+ type: 'procedure',
1872
+ description:
1873
+ 'Update the password for a user account as an administrator.',
1874
+ input: {
1875
+ encoding: 'application/json',
1876
+ schema: {
1877
+ type: 'object',
1878
+ required: ['did', 'password'],
1879
+ properties: {
1880
+ did: {
1881
+ type: 'string',
1882
+ format: 'did',
1883
+ },
1884
+ password: {
1885
+ type: 'string',
1886
+ },
1887
+ },
1888
+ },
1889
+ },
1890
+ },
1891
+ },
1892
+ },
1866
1893
  ComAtprotoAdminUpdateCommunicationTemplate: {
1867
1894
  lexicon: 1,
1868
1895
  id: 'com.atproto.admin.updateCommunicationTemplate',
@@ -5075,6 +5102,8 @@ export const schemaDict = {
5075
5102
  'lex:app.bsky.actor.defs#feedViewPref',
5076
5103
  'lex:app.bsky.actor.defs#threadViewPref',
5077
5104
  'lex:app.bsky.actor.defs#interestsPref',
5105
+ 'lex:app.bsky.actor.defs#mutedWordsPref',
5106
+ 'lex:app.bsky.actor.defs#hiddenPostsPref',
5078
5107
  ],
5079
5108
  },
5080
5109
  },
@@ -8860,6 +8889,8 @@ export const ids = {
8860
8889
  ComAtprotoAdminSendEmail: 'com.atproto.admin.sendEmail',
8861
8890
  ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail',
8862
8891
  ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle',
8892
+ ComAtprotoAdminUpdateAccountPassword:
8893
+ 'com.atproto.admin.updateAccountPassword',
8863
8894
  ComAtprotoAdminUpdateCommunicationTemplate:
8864
8895
  'com.atproto.admin.updateCommunicationTemplate',
8865
8896
  ComAtprotoAdminUpdateSubjectStatus: 'com.atproto.admin.updateSubjectStatus',
@@ -114,6 +114,8 @@ export type Preferences = (
114
114
  | FeedViewPref
115
115
  | ThreadViewPref
116
116
  | InterestsPref
117
+ | MutedWordsPref
118
+ | HiddenPostsPref
117
119
  | { $type: string; [k: string]: unknown }
118
120
  )[]
119
121
 
@@ -0,0 +1,39 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { lexicons } from '../../../../lexicons'
7
+ import { isObj, hasProp } from '../../../../util'
8
+ import { CID } from 'multiformats/cid'
9
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10
+
11
+ export interface QueryParams {}
12
+
13
+ export interface InputSchema {
14
+ did: string
15
+ password: string
16
+ [k: string]: unknown
17
+ }
18
+
19
+ export interface HandlerInput {
20
+ encoding: 'application/json'
21
+ body: InputSchema
22
+ }
23
+
24
+ export interface HandlerError {
25
+ status: number
26
+ message?: string
27
+ }
28
+
29
+ export type HandlerOutput = HandlerError | void
30
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
31
+ auth: HA
32
+ params: QueryParams
33
+ input: HandlerInput
34
+ req: express.Request
35
+ res: express.Response
36
+ }
37
+ export type Handler<HA extends HandlerAuth = never> = (
38
+ ctx: HandlerReqCtx<HA>,
39
+ ) => Promise<HandlerOutput> | HandlerOutput
@@ -559,4 +559,46 @@ describe('account', () => {
559
559
  }),
560
560
  ).resolves.toBeDefined()
561
561
  })
562
+
563
+ it('allows an admin to update password', async () => {
564
+ const tryUnauthed = agent.api.com.atproto.admin.updateAccountPassword({
565
+ did,
566
+ password: 'new-admin-pass',
567
+ })
568
+ await expect(tryUnauthed).rejects.toThrow('Authentication Required')
569
+
570
+ const tryAsModerator = agent.api.com.atproto.admin.updateAccountPassword(
571
+ { did, password: 'new-admin-pass' },
572
+ {
573
+ headers: network.pds.adminAuthHeaders('moderator'),
574
+ encoding: 'application/json',
575
+ },
576
+ )
577
+ await expect(tryAsModerator).rejects.toThrow(
578
+ 'Must be an admin to update an account password',
579
+ )
580
+
581
+ await agent.api.com.atproto.admin.updateAccountPassword(
582
+ { did, password: 'new-admin-password' },
583
+ {
584
+ headers: network.pds.adminAuthHeaders('admin'),
585
+ encoding: 'application/json',
586
+ },
587
+ )
588
+
589
+ // old password fails
590
+ await expect(
591
+ agent.api.com.atproto.server.createSession({
592
+ identifier: did,
593
+ password,
594
+ }),
595
+ ).rejects.toThrow('Invalid identifier or password')
596
+
597
+ await expect(
598
+ agent.api.com.atproto.server.createSession({
599
+ identifier: did,
600
+ password: 'new-admin-password',
601
+ }),
602
+ ).resolves.toBeDefined()
603
+ })
562
604
  })