@atproto/pds 0.4.29 → 0.4.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/account-manager/helpers/account.d.ts +13 -1
  3. package/dist/account-manager/helpers/account.d.ts.map +1 -1
  4. package/dist/account-manager/helpers/account.js +24 -7
  5. package/dist/account-manager/helpers/account.js.map +1 -1
  6. package/dist/account-manager/index.d.ts +4 -1
  7. package/dist/account-manager/index.d.ts.map +1 -1
  8. package/dist/account-manager/index.js +2 -2
  9. package/dist/account-manager/index.js.map +1 -1
  10. package/dist/api/app/bsky/actor/getPreferences.js +1 -1
  11. package/dist/api/app/bsky/actor/getPreferences.js.map +1 -1
  12. package/dist/api/app/bsky/actor/getProfile.js +1 -1
  13. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  14. package/dist/api/app/bsky/actor/getProfiles.js +1 -1
  15. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  16. package/dist/api/app/bsky/actor/putPreferences.js +1 -1
  17. package/dist/api/app/bsky/actor/putPreferences.js.map +1 -1
  18. package/dist/api/app/bsky/feed/getActorLikes.js +1 -1
  19. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  20. package/dist/api/app/bsky/feed/getAuthorFeed.js +1 -1
  21. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  22. package/dist/api/app/bsky/feed/getFeed.js +1 -1
  23. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  24. package/dist/api/app/bsky/feed/getPostThread.js +1 -1
  25. package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
  26. package/dist/api/app/bsky/feed/getTimeline.js +1 -1
  27. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  28. package/dist/api/app/bsky/notification/registerPush.d.ts.map +1 -1
  29. package/dist/api/app/bsky/notification/registerPush.js +4 -1
  30. package/dist/api/app/bsky/notification/registerPush.js.map +1 -1
  31. package/dist/api/chat/index.js +14 -14
  32. package/dist/api/chat/index.js.map +1 -1
  33. package/dist/api/com/atproto/admin/getAccountInfo.d.ts.map +1 -1
  34. package/dist/api/com/atproto/admin/getAccountInfo.js +1 -0
  35. package/dist/api/com/atproto/admin/getAccountInfo.js.map +1 -1
  36. package/dist/api/com/atproto/admin/getSubjectStatus.d.ts.map +1 -1
  37. package/dist/api/com/atproto/admin/getSubjectStatus.js +4 -3
  38. package/dist/api/com/atproto/admin/getSubjectStatus.js.map +1 -1
  39. package/dist/api/com/atproto/admin/updateSubjectStatus.d.ts.map +1 -1
  40. package/dist/api/com/atproto/admin/updateSubjectStatus.js +11 -1
  41. package/dist/api/com/atproto/admin/updateSubjectStatus.js.map +1 -1
  42. package/dist/api/com/atproto/identity/getRecommendedDidCredentials.js +1 -1
  43. package/dist/api/com/atproto/identity/getRecommendedDidCredentials.js.map +1 -1
  44. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js +1 -1
  45. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js.map +1 -1
  46. package/dist/api/com/atproto/identity/signPlcOperation.js +1 -1
  47. package/dist/api/com/atproto/identity/signPlcOperation.js.map +1 -1
  48. package/dist/api/com/atproto/identity/submitPlcOperation.js +1 -1
  49. package/dist/api/com/atproto/identity/submitPlcOperation.js.map +1 -1
  50. package/dist/api/com/atproto/identity/updateHandle.js +1 -1
  51. package/dist/api/com/atproto/identity/updateHandle.js.map +1 -1
  52. package/dist/api/com/atproto/repo/applyWrites.d.ts.map +1 -1
  53. package/dist/api/com/atproto/repo/applyWrites.js +4 -1
  54. package/dist/api/com/atproto/repo/applyWrites.js.map +1 -1
  55. package/dist/api/com/atproto/repo/createRecord.d.ts.map +1 -1
  56. package/dist/api/com/atproto/repo/createRecord.js +4 -1
  57. package/dist/api/com/atproto/repo/createRecord.js.map +1 -1
  58. package/dist/api/com/atproto/repo/deleteRecord.d.ts.map +1 -1
  59. package/dist/api/com/atproto/repo/deleteRecord.js +4 -1
  60. package/dist/api/com/atproto/repo/deleteRecord.js.map +1 -1
  61. package/dist/api/com/atproto/repo/importRepo.d.ts.map +1 -1
  62. package/dist/api/com/atproto/repo/importRepo.js +3 -1
  63. package/dist/api/com/atproto/repo/importRepo.js.map +1 -1
  64. package/dist/api/com/atproto/repo/listMissingBlobs.js +1 -1
  65. package/dist/api/com/atproto/repo/listMissingBlobs.js.map +1 -1
  66. package/dist/api/com/atproto/repo/putRecord.d.ts.map +1 -1
  67. package/dist/api/com/atproto/repo/putRecord.js +4 -1
  68. package/dist/api/com/atproto/repo/putRecord.js.map +1 -1
  69. package/dist/api/com/atproto/repo/uploadBlob.d.ts.map +1 -1
  70. package/dist/api/com/atproto/repo/uploadBlob.js +3 -1
  71. package/dist/api/com/atproto/repo/uploadBlob.js.map +1 -1
  72. package/dist/api/com/atproto/server/activateAccount.js +1 -1
  73. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  74. package/dist/api/com/atproto/server/checkAccountStatus.js +1 -1
  75. package/dist/api/com/atproto/server/checkAccountStatus.js.map +1 -1
  76. package/dist/api/com/atproto/server/confirmEmail.js +1 -1
  77. package/dist/api/com/atproto/server/confirmEmail.js.map +1 -1
  78. package/dist/api/com/atproto/server/createAppPassword.d.ts.map +1 -1
  79. package/dist/api/com/atproto/server/createAppPassword.js +3 -1
  80. package/dist/api/com/atproto/server/createAppPassword.js.map +1 -1
  81. package/dist/api/com/atproto/server/createSession.d.ts.map +1 -1
  82. package/dist/api/com/atproto/server/createSession.js +2 -0
  83. package/dist/api/com/atproto/server/createSession.js.map +1 -1
  84. package/dist/api/com/atproto/server/deactivateAccount.js +1 -1
  85. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  86. package/dist/api/com/atproto/server/getAccountInviteCodes.js +1 -1
  87. package/dist/api/com/atproto/server/getAccountInviteCodes.js.map +1 -1
  88. package/dist/api/com/atproto/server/getServiceAuth.js +1 -1
  89. package/dist/api/com/atproto/server/getServiceAuth.js.map +1 -1
  90. package/dist/api/com/atproto/server/getSession.d.ts.map +1 -1
  91. package/dist/api/com/atproto/server/getSession.js +7 -2
  92. package/dist/api/com/atproto/server/getSession.js.map +1 -1
  93. package/dist/api/com/atproto/server/listAppPasswords.js +1 -1
  94. package/dist/api/com/atproto/server/listAppPasswords.js.map +1 -1
  95. package/dist/api/com/atproto/server/refreshSession.d.ts.map +1 -1
  96. package/dist/api/com/atproto/server/refreshSession.js +2 -0
  97. package/dist/api/com/atproto/server/refreshSession.js.map +1 -1
  98. package/dist/api/com/atproto/server/requestAccountDelete.js +1 -1
  99. package/dist/api/com/atproto/server/requestAccountDelete.js.map +1 -1
  100. package/dist/api/com/atproto/server/requestEmailConfirmation.js +1 -1
  101. package/dist/api/com/atproto/server/requestEmailConfirmation.js.map +1 -1
  102. package/dist/api/com/atproto/server/requestEmailUpdate.js +1 -1
  103. package/dist/api/com/atproto/server/requestEmailUpdate.js.map +1 -1
  104. package/dist/api/com/atproto/server/revokeAppPassword.js +1 -1
  105. package/dist/api/com/atproto/server/revokeAppPassword.js.map +1 -1
  106. package/dist/api/com/atproto/server/updateEmail.js +1 -1
  107. package/dist/api/com/atproto/server/updateEmail.js.map +1 -1
  108. package/dist/api/com/atproto/sync/getRepoStatus.js +1 -1
  109. package/dist/api/com/atproto/sync/getRepoStatus.js.map +1 -1
  110. package/dist/api/com/atproto/sync/listRepos.js +2 -2
  111. package/dist/api/com/atproto/sync/listRepos.js.map +1 -1
  112. package/dist/api/com/atproto/sync/util.d.ts +1 -8
  113. package/dist/api/com/atproto/sync/util.d.ts.map +1 -1
  114. package/dist/api/com/atproto/sync/util.js +1 -17
  115. package/dist/api/com/atproto/sync/util.js.map +1 -1
  116. package/dist/api/com/atproto/temp/checkSignupQueue.d.ts.map +1 -1
  117. package/dist/api/com/atproto/temp/checkSignupQueue.js +4 -1
  118. package/dist/api/com/atproto/temp/checkSignupQueue.js.map +1 -1
  119. package/dist/auth-verifier.d.ts +13 -7
  120. package/dist/auth-verifier.d.ts.map +1 -1
  121. package/dist/auth-verifier.js +29 -46
  122. package/dist/auth-verifier.js.map +1 -1
  123. package/dist/lexicon/lexicons.d.ts +44 -0
  124. package/dist/lexicon/lexicons.d.ts.map +1 -1
  125. package/dist/lexicon/lexicons.js +44 -0
  126. package/dist/lexicon/lexicons.js.map +1 -1
  127. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +1 -0
  128. package/dist/lexicon/types/com/atproto/admin/defs.d.ts.map +1 -1
  129. package/dist/lexicon/types/com/atproto/admin/defs.js.map +1 -1
  130. package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts +1 -0
  131. package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts.map +1 -1
  132. package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts +1 -0
  133. package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts.map +1 -1
  134. package/dist/lexicon/types/com/atproto/server/createSession.d.ts +3 -0
  135. package/dist/lexicon/types/com/atproto/server/createSession.d.ts.map +1 -1
  136. package/dist/lexicon/types/com/atproto/server/getSession.d.ts +3 -0
  137. package/dist/lexicon/types/com/atproto/server/getSession.d.ts.map +1 -1
  138. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +3 -0
  139. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts.map +1 -1
  140. package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +2 -0
  141. package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts.map +1 -1
  142. package/dist/lexicon/types/tools/ozone/moderation/defs.js.map +1 -1
  143. package/dist/pipethrough.d.ts.map +1 -1
  144. package/dist/pipethrough.js +17 -14
  145. package/dist/pipethrough.js.map +1 -1
  146. package/package.json +4 -4
  147. package/src/account-manager/helpers/account.ts +30 -6
  148. package/src/account-manager/index.ts +2 -2
  149. package/src/api/app/bsky/actor/getPreferences.ts +1 -1
  150. package/src/api/app/bsky/actor/getProfile.ts +1 -1
  151. package/src/api/app/bsky/actor/getProfiles.ts +1 -1
  152. package/src/api/app/bsky/actor/putPreferences.ts +1 -1
  153. package/src/api/app/bsky/feed/getActorLikes.ts +1 -1
  154. package/src/api/app/bsky/feed/getAuthorFeed.ts +1 -1
  155. package/src/api/app/bsky/feed/getFeed.ts +1 -1
  156. package/src/api/app/bsky/feed/getPostThread.ts +1 -1
  157. package/src/api/app/bsky/feed/getTimeline.ts +1 -1
  158. package/src/api/app/bsky/notification/registerPush.ts +4 -1
  159. package/src/api/chat/index.ts +14 -14
  160. package/src/api/com/atproto/admin/getAccountInfo.ts +1 -0
  161. package/src/api/com/atproto/admin/getSubjectStatus.ts +4 -3
  162. package/src/api/com/atproto/admin/updateSubjectStatus.ts +11 -1
  163. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +1 -1
  164. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +1 -1
  165. package/src/api/com/atproto/identity/signPlcOperation.ts +1 -1
  166. package/src/api/com/atproto/identity/submitPlcOperation.ts +1 -1
  167. package/src/api/com/atproto/identity/updateHandle.ts +1 -1
  168. package/src/api/com/atproto/repo/applyWrites.ts +4 -1
  169. package/src/api/com/atproto/repo/createRecord.ts +4 -1
  170. package/src/api/com/atproto/repo/deleteRecord.ts +4 -1
  171. package/src/api/com/atproto/repo/importRepo.ts +3 -1
  172. package/src/api/com/atproto/repo/listMissingBlobs.ts +1 -1
  173. package/src/api/com/atproto/repo/putRecord.ts +4 -1
  174. package/src/api/com/atproto/repo/uploadBlob.ts +3 -1
  175. package/src/api/com/atproto/server/activateAccount.ts +1 -1
  176. package/src/api/com/atproto/server/checkAccountStatus.ts +1 -1
  177. package/src/api/com/atproto/server/confirmEmail.ts +1 -1
  178. package/src/api/com/atproto/server/createAppPassword.ts +3 -1
  179. package/src/api/com/atproto/server/createSession.ts +2 -0
  180. package/src/api/com/atproto/server/deactivateAccount.ts +1 -1
  181. package/src/api/com/atproto/server/getAccountInviteCodes.ts +1 -1
  182. package/src/api/com/atproto/server/getServiceAuth.ts +1 -1
  183. package/src/api/com/atproto/server/getSession.ts +7 -2
  184. package/src/api/com/atproto/server/listAppPasswords.ts +1 -1
  185. package/src/api/com/atproto/server/refreshSession.ts +2 -0
  186. package/src/api/com/atproto/server/requestAccountDelete.ts +1 -1
  187. package/src/api/com/atproto/server/requestEmailConfirmation.ts +1 -1
  188. package/src/api/com/atproto/server/requestEmailUpdate.ts +1 -1
  189. package/src/api/com/atproto/server/revokeAppPassword.ts +1 -1
  190. package/src/api/com/atproto/server/updateEmail.ts +1 -1
  191. package/src/api/com/atproto/sync/getRepoStatus.ts +2 -2
  192. package/src/api/com/atproto/sync/listRepos.ts +1 -1
  193. package/src/api/com/atproto/sync/util.ts +1 -24
  194. package/src/api/com/atproto/temp/checkSignupQueue.ts +4 -1
  195. package/src/auth-verifier.ts +62 -47
  196. package/src/lexicon/lexicons.ts +47 -0
  197. package/src/lexicon/types/com/atproto/admin/defs.ts +1 -0
  198. package/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +1 -0
  199. package/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts +1 -0
  200. package/src/lexicon/types/com/atproto/server/createSession.ts +3 -0
  201. package/src/lexicon/types/com/atproto/server/getSession.ts +3 -0
  202. package/src/lexicon/types/com/atproto/server/refreshSession.ts +3 -0
  203. package/src/lexicon/types/tools/ozone/moderation/defs.ts +2 -0
  204. package/src/pipethrough.ts +5 -4
  205. package/tests/account-deactivation.test.ts +31 -2
  206. package/tests/auth.test.ts +3 -0
@@ -24,7 +24,13 @@ export enum AuthScope {
24
24
  Refresh = 'com.atproto.refresh',
25
25
  AppPass = 'com.atproto.appPass',
26
26
  AppPassPrivileged = 'com.atproto.appPassPrivileged',
27
- Deactivated = 'com.atproto.deactivated',
27
+ SignupQueued = 'com.atproto.signupQueued',
28
+ }
29
+
30
+ export type AccessOpts = {
31
+ additional: AuthScope[]
32
+ checkTakedown: boolean
33
+ checkDeactivated: boolean
28
34
  }
29
35
 
30
36
  export enum RoleStatus {
@@ -115,55 +121,40 @@ export class AuthVerifier {
115
121
 
116
122
  // verifiers (arrow fns to preserve scope)
117
123
 
118
- access = (ctx: ReqCtx): Promise<AccessOutput> => {
119
- return this.validateAccessToken(ctx.req, [
120
- AuthScope.Access,
121
- AuthScope.AppPassPrivileged,
122
- AuthScope.AppPass,
123
- ])
124
- }
125
-
126
- accessCheckTakedown = async (ctx: ReqCtx): Promise<AccessOutput> => {
127
- const result = await this.validateAccessToken(ctx.req, [
128
- AuthScope.Access,
129
- AuthScope.AppPassPrivileged,
130
- AuthScope.AppPass,
131
- ])
132
- const found = await this.accountManager.getAccount(result.credentials.did, {
133
- includeDeactivated: true,
134
- })
135
- if (!found) {
136
- // will be turned into ExpiredToken for the client if proxied by entryway
137
- throw new ForbiddenError('Account not found', 'AccountNotFound')
138
- }
139
- if (softDeleted(found)) {
140
- throw new AuthRequiredError(
141
- 'Account has been taken down',
142
- 'AccountTakedown',
124
+ accessStandard =
125
+ (opts: Partial<AccessOpts> = {}) =>
126
+ (ctx: ReqCtx): Promise<AccessOutput> => {
127
+ return this.validateAccessToken(
128
+ ctx.req,
129
+ [
130
+ AuthScope.Access,
131
+ AuthScope.AppPassPrivileged,
132
+ AuthScope.AppPass,
133
+ ...(opts.additional ?? []),
134
+ ],
135
+ opts,
143
136
  )
144
137
  }
145
- return result
146
- }
147
-
148
- accessFull = (ctx: ReqCtx): Promise<AccessOutput> => {
149
- return this.validateAccessToken(ctx.req, [AuthScope.Access])
150
- }
151
138
 
152
- accessAppPassPrivileged = (ctx: ReqCtx): Promise<AccessOutput> => {
153
- return this.validateAccessToken(ctx.req, [
154
- AuthScope.Access,
155
- AuthScope.AppPassPrivileged,
156
- ])
157
- }
139
+ accessFull =
140
+ (opts: Partial<AccessOpts> = {}) =>
141
+ (ctx: ReqCtx): Promise<AccessOutput> => {
142
+ return this.validateAccessToken(
143
+ ctx.req,
144
+ [AuthScope.Access, ...(opts.additional ?? [])],
145
+ opts,
146
+ )
147
+ }
158
148
 
159
- accessDeactived = (ctx: ReqCtx): Promise<AccessOutput> => {
160
- return this.validateAccessToken(ctx.req, [
161
- AuthScope.Access,
162
- AuthScope.AppPass,
163
- AuthScope.AppPassPrivileged,
164
- AuthScope.Deactivated,
165
- ])
166
- }
149
+ accessPrivileged =
150
+ (opts: Partial<AccessOpts> = {}) =>
151
+ (ctx: ReqCtx): Promise<AccessOutput> => {
152
+ return this.validateAccessToken(ctx.req, [
153
+ AuthScope.Access,
154
+ AuthScope.AppPassPrivileged,
155
+ ...(opts.additional ?? []),
156
+ ])
157
+ }
167
158
 
168
159
  refresh = async (ctx: ReqCtx): Promise<RefreshOutput> => {
169
160
  const { did, scope, token, audience, payload } =
@@ -205,7 +196,7 @@ export class AuthVerifier {
205
196
  ctx: ReqCtx,
206
197
  ): Promise<AccessOutput | AdminTokenOutput | NullOutput> => {
207
198
  if (isBearerToken(ctx.req)) {
208
- return await this.access(ctx)
199
+ return await this.accessStandard()(ctx)
209
200
  } else if (isBasicToken(ctx.req)) {
210
201
  return await this.adminToken(ctx)
211
202
  } else {
@@ -308,12 +299,36 @@ export class AuthVerifier {
308
299
  async validateAccessToken(
309
300
  req: express.Request,
310
301
  scopes: AuthScope[],
302
+ opts?: { checkTakedown?: boolean; checkDeactivated?: boolean },
311
303
  ): Promise<AccessOutput> {
312
304
  const { did, scope, token, audience } = await this.validateBearerToken(
313
305
  req,
314
306
  scopes,
315
307
  { audience: this.dids.pds },
316
308
  )
309
+ const { checkTakedown = false, checkDeactivated = false } = opts ?? {}
310
+ if (checkTakedown || checkDeactivated) {
311
+ const found = await this.accountManager.getAccount(did, {
312
+ includeDeactivated: true,
313
+ includeTakenDown: true,
314
+ })
315
+ if (!found) {
316
+ // will be turned into ExpiredToken for the client if proxied by entryway
317
+ throw new ForbiddenError('Account not found', 'AccountNotFound')
318
+ }
319
+ if (checkTakedown && softDeleted(found)) {
320
+ throw new AuthRequiredError(
321
+ 'Account has been taken down',
322
+ 'AccountTakedown',
323
+ )
324
+ }
325
+ if (checkDeactivated && found.deactivatedAt) {
326
+ throw new AuthRequiredError(
327
+ 'Account is deactivated',
328
+ 'AccountDeactivated',
329
+ )
330
+ }
331
+ }
317
332
  return {
318
333
  credentials: {
319
334
  type: 'access',
@@ -66,6 +66,10 @@ export const schemaDict = {
66
66
  inviteNote: {
67
67
  type: 'string',
68
68
  },
69
+ deactivatedAt: {
70
+ type: 'string',
71
+ format: 'datetime',
72
+ },
69
73
  },
70
74
  },
71
75
  repoRef: {
@@ -364,6 +368,10 @@ export const schemaDict = {
364
368
  type: 'ref',
365
369
  ref: 'lex:com.atproto.admin.defs#statusAttr',
366
370
  },
371
+ deactivated: {
372
+ type: 'ref',
373
+ ref: 'lex:com.atproto.admin.defs#statusAttr',
374
+ },
367
375
  },
368
376
  },
369
377
  },
@@ -527,6 +535,10 @@ export const schemaDict = {
527
535
  type: 'ref',
528
536
  ref: 'lex:com.atproto.admin.defs#statusAttr',
529
537
  },
538
+ deactivated: {
539
+ type: 'ref',
540
+ ref: 'lex:com.atproto.admin.defs#statusAttr',
541
+ },
530
542
  },
531
543
  },
532
544
  },
@@ -2255,6 +2267,15 @@ export const schemaDict = {
2255
2267
  emailAuthFactor: {
2256
2268
  type: 'boolean',
2257
2269
  },
2270
+ active: {
2271
+ type: 'boolean',
2272
+ },
2273
+ status: {
2274
+ type: 'string',
2275
+ description:
2276
+ 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.',
2277
+ knownValues: ['takendown', 'suspended', 'deactivated'],
2278
+ },
2258
2279
  },
2259
2280
  },
2260
2281
  },
@@ -2591,6 +2612,15 @@ export const schemaDict = {
2591
2612
  didDoc: {
2592
2613
  type: 'unknown',
2593
2614
  },
2615
+ active: {
2616
+ type: 'boolean',
2617
+ },
2618
+ status: {
2619
+ type: 'string',
2620
+ description:
2621
+ 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.',
2622
+ knownValues: ['takendown', 'suspended', 'deactivated'],
2623
+ },
2594
2624
  },
2595
2625
  },
2596
2626
  },
@@ -2675,6 +2705,15 @@ export const schemaDict = {
2675
2705
  didDoc: {
2676
2706
  type: 'unknown',
2677
2707
  },
2708
+ active: {
2709
+ type: 'boolean',
2710
+ },
2711
+ status: {
2712
+ type: 'string',
2713
+ description:
2714
+ "Hosting status of the account. If not specified, then assume 'active'.",
2715
+ knownValues: ['takendown', 'suspended', 'deactivated'],
2716
+ },
2678
2717
  },
2679
2718
  },
2680
2719
  },
@@ -9999,6 +10038,10 @@ export const schemaDict = {
9999
10038
  inviteNote: {
10000
10039
  type: 'string',
10001
10040
  },
10041
+ deactivatedAt: {
10042
+ type: 'string',
10043
+ format: 'datetime',
10044
+ },
10002
10045
  },
10003
10046
  },
10004
10047
  repoViewDetail: {
@@ -10064,6 +10107,10 @@ export const schemaDict = {
10064
10107
  type: 'string',
10065
10108
  format: 'datetime',
10066
10109
  },
10110
+ deactivatedAt: {
10111
+ type: 'string',
10112
+ format: 'datetime',
10113
+ },
10067
10114
  },
10068
10115
  },
10069
10116
  repoViewNotFound: {
@@ -36,6 +36,7 @@ export interface AccountView {
36
36
  invitesDisabled?: boolean
37
37
  emailConfirmedAt?: string
38
38
  inviteNote?: string
39
+ deactivatedAt?: string
39
40
  [k: string]: unknown
40
41
  }
41
42
 
@@ -25,6 +25,7 @@ export interface OutputSchema {
25
25
  | ComAtprotoAdminDefs.RepoBlobRef
26
26
  | { $type: string; [k: string]: unknown }
27
27
  takedown?: ComAtprotoAdminDefs.StatusAttr
28
+ deactivated?: ComAtprotoAdminDefs.StatusAttr
28
29
  [k: string]: unknown
29
30
  }
30
31
 
@@ -19,6 +19,7 @@ export interface InputSchema {
19
19
  | ComAtprotoAdminDefs.RepoBlobRef
20
20
  | { $type: string; [k: string]: unknown }
21
21
  takedown?: ComAtprotoAdminDefs.StatusAttr
22
+ deactivated?: ComAtprotoAdminDefs.StatusAttr
22
23
  [k: string]: unknown
23
24
  }
24
25
 
@@ -27,6 +27,9 @@ export interface OutputSchema {
27
27
  email?: string
28
28
  emailConfirmed?: boolean
29
29
  emailAuthFactor?: boolean
30
+ active?: boolean
31
+ /** If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. */
32
+ status?: 'takendown' | 'suspended' | 'deactivated' | (string & {})
30
33
  [k: string]: unknown
31
34
  }
32
35
 
@@ -19,6 +19,9 @@ export interface OutputSchema {
19
19
  emailConfirmed?: boolean
20
20
  emailAuthFactor?: boolean
21
21
  didDoc?: {}
22
+ active?: boolean
23
+ /** If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. */
24
+ status?: 'takendown' | 'suspended' | 'deactivated' | (string & {})
22
25
  [k: string]: unknown
23
26
  }
24
27
 
@@ -18,6 +18,9 @@ export interface OutputSchema {
18
18
  handle: string
19
19
  did: string
20
20
  didDoc?: {}
21
+ active?: boolean
22
+ /** Hosting status of the account. If not specified, then assume 'active'. */
23
+ status?: 'takendown' | 'suspended' | 'deactivated' | (string & {})
21
24
  [k: string]: unknown
22
25
  }
23
26
 
@@ -478,6 +478,7 @@ export interface RepoView {
478
478
  invitedBy?: ComAtprotoServerDefs.InviteCode
479
479
  invitesDisabled?: boolean
480
480
  inviteNote?: string
481
+ deactivatedAt?: string
481
482
  [k: string]: unknown
482
483
  }
483
484
 
@@ -506,6 +507,7 @@ export interface RepoViewDetail {
506
507
  invitesDisabled?: boolean
507
508
  inviteNote?: string
508
509
  emailConfirmedAt?: string
510
+ deactivatedAt?: string
509
511
  [k: string]: unknown
510
512
  }
511
513
 
@@ -15,12 +15,12 @@ import { httpLogger } from './logger'
15
15
  import { getServiceEndpoint, noUndefinedVals } from '@atproto/common'
16
16
  import AppContext from './context'
17
17
 
18
- export const proxyHandler =
19
- (ctx: AppContext): CatchallHandler =>
20
- async (req, res, next) => {
18
+ export const proxyHandler = (ctx: AppContext): CatchallHandler => {
19
+ const accessStandard = ctx.authVerifier.accessStandard()
20
+ return async (req, res, next) => {
21
21
  try {
22
22
  const { url, aud } = await formatUrlAndAud(ctx, req)
23
- const auth = await ctx.authVerifier.access({ req })
23
+ const auth = await accessStandard({ req })
24
24
  const headers = await formatHeaders(ctx, req, aud, auth.credentials.did)
25
25
  const body = stream.Readable.toWeb(req)
26
26
  const reqInit = formatReqInit(req, headers, body)
@@ -31,6 +31,7 @@ export const proxyHandler =
31
31
  }
32
32
  return next()
33
33
  }
34
+ }
34
35
 
35
36
  export const pipethrough = async (
36
37
  ctx: AppContext,
@@ -56,6 +56,14 @@ describe('account deactivation', () => {
56
56
  active: false,
57
57
  status: 'deactivated',
58
58
  })
59
+
60
+ const adminRes = await agent.com.atproto.admin.getAccountInfo(
61
+ {
62
+ did: alice,
63
+ },
64
+ { headers: network.pds.adminAuthHeaders() },
65
+ )
66
+ expect(typeof adminRes.data.deactivatedAt).toBeDefined()
59
67
  })
60
68
 
61
69
  it('no longer serves repo data', async () => {
@@ -109,11 +117,19 @@ describe('account deactivation', () => {
109
117
  ).rejects.toThrow()
110
118
  })
111
119
 
112
- it('still allows login', async () => {
113
- await agent.com.atproto.server.createSession({
120
+ it('still allows login and returns status', async () => {
121
+ const res = await agent.com.atproto.server.createSession({
114
122
  identifier: alice,
115
123
  password: sc.accounts[alice].password,
116
124
  })
125
+ expect(res.data.status).toEqual('deactivated')
126
+ })
127
+
128
+ it('returns status on getSession', async () => {
129
+ const res = await agent.com.atproto.server.getSession(undefined, {
130
+ headers: sc.getHeaders(alice),
131
+ })
132
+ expect(res.data.status).toEqual('deactivated')
117
133
  })
118
134
 
119
135
  it('does not allow writes', async () => {
@@ -169,6 +185,19 @@ describe('account deactivation', () => {
169
185
  await agent.com.atproto.server.activateAccount(undefined, {
170
186
  headers: sc.getHeaders(alice),
171
187
  })
188
+
172
189
  await agent.com.atproto.sync.getRepo({ did: alice })
190
+
191
+ const statusRes = await agent.com.atproto.sync.getRepoStatus({ did: alice })
192
+ expect(statusRes.data.active).toBe(true)
193
+ expect(statusRes.data.status).toBeUndefined()
194
+
195
+ const adminRes = await agent.com.atproto.admin.getAccountInfo(
196
+ {
197
+ did: alice,
198
+ },
199
+ { headers: network.pds.adminAuthHeaders() },
200
+ )
201
+ expect(adminRes.data.deactivatedAt).toBeUndefined()
173
202
  })
174
203
  })
@@ -62,6 +62,7 @@ describe('auth', () => {
62
62
  handle: account.handle,
63
63
  email,
64
64
  emailConfirmed: false,
65
+ active: true,
65
66
  })
66
67
  // Valid refresh token
67
68
  const nextSession = await refreshSession(account.refreshJwt)
@@ -91,6 +92,7 @@ describe('auth', () => {
91
92
  handle: session.handle,
92
93
  email,
93
94
  emailConfirmed: false,
95
+ active: true,
94
96
  })
95
97
  // Valid refresh token
96
98
  const nextSession = await refreshSession(session.refreshJwt)
@@ -135,6 +137,7 @@ describe('auth', () => {
135
137
  handle: session.handle,
136
138
  email,
137
139
  emailConfirmed: false,
140
+ active: true,
138
141
  })
139
142
  // Valid refresh token
140
143
  const nextSession = await refreshSession(session.refreshJwt)