@atproto/pds 0.4.25 → 0.4.26

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/account-manager/db/migrations/003-privileged-app-passwords.d.ts +4 -0
  3. package/dist/account-manager/db/migrations/003-privileged-app-passwords.d.ts.map +1 -0
  4. package/dist/account-manager/db/migrations/003-privileged-app-passwords.js +15 -0
  5. package/dist/account-manager/db/migrations/003-privileged-app-passwords.js.map +1 -0
  6. package/dist/account-manager/db/migrations/index.d.ts +2 -0
  7. package/dist/account-manager/db/migrations/index.d.ts.map +1 -1
  8. package/dist/account-manager/db/migrations/index.js +2 -0
  9. package/dist/account-manager/db/migrations/index.js.map +1 -1
  10. package/dist/account-manager/db/schema/app-password.d.ts +1 -0
  11. package/dist/account-manager/db/schema/app-password.d.ts.map +1 -1
  12. package/dist/account-manager/db/schema/app-password.js.map +1 -1
  13. package/dist/account-manager/helpers/auth.d.ts +9 -4
  14. package/dist/account-manager/helpers/auth.d.ts.map +1 -1
  15. package/dist/account-manager/helpers/auth.js +30 -5
  16. package/dist/account-manager/helpers/auth.js.map +1 -1
  17. package/dist/account-manager/helpers/password.d.ts +7 -2
  18. package/dist/account-manager/helpers/password.d.ts.map +1 -1
  19. package/dist/account-manager/helpers/password.js +17 -4
  20. package/dist/account-manager/helpers/password.js.map +1 -1
  21. package/dist/account-manager/index.d.ts +5 -3
  22. package/dist/account-manager/index.d.ts.map +1 -1
  23. package/dist/account-manager/index.js +7 -7
  24. package/dist/account-manager/index.js.map +1 -1
  25. package/dist/api/chat/index.js +14 -14
  26. package/dist/api/chat/index.js.map +1 -1
  27. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js +1 -1
  28. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js.map +1 -1
  29. package/dist/api/com/atproto/identity/signPlcOperation.js +1 -1
  30. package/dist/api/com/atproto/identity/signPlcOperation.js.map +1 -1
  31. package/dist/api/com/atproto/repo/importRepo.js +1 -1
  32. package/dist/api/com/atproto/repo/importRepo.js.map +1 -1
  33. package/dist/api/com/atproto/server/activateAccount.js +1 -1
  34. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  35. package/dist/api/com/atproto/server/createAppPassword.d.ts.map +1 -1
  36. package/dist/api/com/atproto/server/createAppPassword.js +2 -2
  37. package/dist/api/com/atproto/server/createAppPassword.js.map +1 -1
  38. package/dist/api/com/atproto/server/createSession.d.ts.map +1 -1
  39. package/dist/api/com/atproto/server/createSession.js +4 -4
  40. package/dist/api/com/atproto/server/createSession.js.map +1 -1
  41. package/dist/api/com/atproto/server/deactivateAccount.js +1 -1
  42. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  43. package/dist/api/com/atproto/server/getAccountInviteCodes.js +1 -1
  44. package/dist/api/com/atproto/server/getAccountInviteCodes.js.map +1 -1
  45. package/dist/api/com/atproto/server/getServiceAuth.js +1 -1
  46. package/dist/api/com/atproto/server/getServiceAuth.js.map +1 -1
  47. package/dist/api/com/atproto/server/updateEmail.js +1 -1
  48. package/dist/api/com/atproto/server/updateEmail.js.map +1 -1
  49. package/dist/auth-verifier.d.ts +3 -1
  50. package/dist/auth-verifier.d.ts.map +1 -1
  51. package/dist/auth-verifier.js +16 -1
  52. package/dist/auth-verifier.js.map +1 -1
  53. package/dist/lexicon/lexicons.d.ts +10 -0
  54. package/dist/lexicon/lexicons.d.ts.map +1 -1
  55. package/dist/lexicon/lexicons.js +10 -0
  56. package/dist/lexicon/lexicons.js.map +1 -1
  57. package/dist/lexicon/types/com/atproto/server/createAppPassword.d.ts +3 -0
  58. package/dist/lexicon/types/com/atproto/server/createAppPassword.d.ts.map +1 -1
  59. package/dist/lexicon/types/com/atproto/server/createAppPassword.js.map +1 -1
  60. package/dist/lexicon/types/com/atproto/server/listAppPasswords.d.ts +1 -0
  61. package/dist/lexicon/types/com/atproto/server/listAppPasswords.d.ts.map +1 -1
  62. package/dist/lexicon/types/com/atproto/server/listAppPasswords.js.map +1 -1
  63. package/package.json +3 -3
  64. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +12 -0
  65. package/src/account-manager/db/migrations/index.ts +2 -0
  66. package/src/account-manager/db/schema/app-password.ts +1 -0
  67. package/src/account-manager/helpers/auth.ts +32 -4
  68. package/src/account-manager/helpers/password.ts +23 -5
  69. package/src/account-manager/index.ts +11 -9
  70. package/src/api/chat/index.ts +14 -14
  71. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +1 -1
  72. package/src/api/com/atproto/identity/signPlcOperation.ts +1 -1
  73. package/src/api/com/atproto/repo/importRepo.ts +1 -1
  74. package/src/api/com/atproto/server/activateAccount.ts +1 -1
  75. package/src/api/com/atproto/server/createAppPassword.ts +3 -1
  76. package/src/api/com/atproto/server/createSession.ts +5 -4
  77. package/src/api/com/atproto/server/deactivateAccount.ts +1 -1
  78. package/src/api/com/atproto/server/getAccountInviteCodes.ts +1 -1
  79. package/src/api/com/atproto/server/getServiceAuth.ts +1 -1
  80. package/src/api/com/atproto/server/updateEmail.ts +1 -1
  81. package/src/auth-verifier.ts +12 -1
  82. package/src/lexicon/lexicons.ts +11 -0
  83. package/src/lexicon/types/com/atproto/server/createAppPassword.ts +3 -0
  84. package/src/lexicon/types/com/atproto/server/listAppPasswords.ts +1 -0
  85. package/tests/app-passwords.test.ts +108 -7
@@ -9,6 +9,8 @@ export interface QueryParams {
9
9
  export interface InputSchema {
10
10
  /** A short name for the App Password, to help distinguish them. */
11
11
  name: string;
12
+ /** If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients. */
13
+ privileged?: boolean;
12
14
  [k: string]: unknown;
13
15
  }
14
16
  export type OutputSchema = AppPassword;
@@ -41,6 +43,7 @@ export interface AppPassword {
41
43
  name: string;
42
44
  password: string;
43
45
  createdAt: string;
46
+ privileged?: boolean;
44
47
  [k: string]: unknown;
45
48
  }
46
49
  export declare function isAppPassword(v: unknown): v is AppPassword;
@@ -1 +1 @@
1
- {"version":3,"file":"createAppPassword.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/createAppPassword.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEtE,MAAM,WAAW,WAAW;CAAG;AAE/B,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAA;AAEtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAM1D;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAKhE"}
1
+ {"version":3,"file":"createAppPassword.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/createAppPassword.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEtE,MAAM,WAAW,WAAW;CAAG;AAE/B,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,0HAA0H;IAC1H,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAA;AAEtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAM1D;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAKhE"}
@@ -1 +1 @@
1
- {"version":3,"file":"createAppPassword.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/createAppPassword.ts"],"names":[],"mappings":";;;AAKA,mDAA+C;AAC/C,2CAAiD;AAkDjD,SAAgB,aAAa,CAAC,CAAU;IACtC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,kDAAkD,CAC/D,CAAA;AACH,CAAC;AAND,sCAMC;AAED,SAAgB,mBAAmB,CAAC,CAAU;IAC5C,OAAO,mBAAQ,CAAC,QAAQ,CACtB,kDAAkD,EAClD,CAAC,CACF,CAAA;AACH,CAAC;AALD,kDAKC"}
1
+ {"version":3,"file":"createAppPassword.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/createAppPassword.ts"],"names":[],"mappings":";;;AAKA,mDAA+C;AAC/C,2CAAiD;AAqDjD,SAAgB,aAAa,CAAC,CAAU;IACtC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,kDAAkD,CAC/D,CAAA;AACH,CAAC;AAND,sCAMC;AAED,SAAgB,mBAAmB,CAAC,CAAU;IAC5C,OAAO,mBAAQ,CAAC,QAAQ,CACtB,kDAAkD,EAClD,CAAC,CACF,CAAA;AACH,CAAC;AALD,kDAKC"}
@@ -36,6 +36,7 @@ export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) =
36
36
  export interface AppPassword {
37
37
  name: string;
38
38
  createdAt: string;
39
+ privileged?: boolean;
39
40
  [k: string]: unknown;
40
41
  }
41
42
  export declare function isAppPassword(v: unknown): v is AppPassword;
@@ -1 +1 @@
1
- {"version":3,"file":"listAppPasswords.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/listAppPasswords.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEtE,MAAM,WAAW,WAAW;CAAG;AAE/B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,EAAE,CAAA;IACxB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAM1D;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAEhE"}
1
+ {"version":3,"file":"listAppPasswords.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/listAppPasswords.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEtE,MAAM,WAAW,WAAW;CAAG;AAE/B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,EAAE,CAAA;IACxB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAM1D;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAEhE"}
@@ -1 +1 @@
1
- {"version":3,"file":"listAppPasswords.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/listAppPasswords.ts"],"names":[],"mappings":";;;AAKA,mDAA+C;AAC/C,2CAAiD;AA6CjD,SAAgB,aAAa,CAAC,CAAU;IACtC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,iDAAiD,CAC9D,CAAA;AACH,CAAC;AAND,sCAMC;AAED,SAAgB,mBAAmB,CAAC,CAAU;IAC5C,OAAO,mBAAQ,CAAC,QAAQ,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAA;AAChF,CAAC;AAFD,kDAEC"}
1
+ {"version":3,"file":"listAppPasswords.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/com/atproto/server/listAppPasswords.ts"],"names":[],"mappings":";;;AAKA,mDAA+C;AAC/C,2CAAiD;AA8CjD,SAAgB,aAAa,CAAC,CAAU;IACtC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,iDAAiD,CAC9D,CAAA;AACH,CAAC;AAND,sCAMC;AAED,SAAgB,mBAAmB,CAAC,CAAU;IAC5C,OAAO,mBAAQ,CAAC,QAAQ,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAA;AAChF,CAAC;AAFD,kDAEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/pds",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of atproto Personal Data Server (PDS)",
6
6
  "keywords": [
@@ -43,12 +43,12 @@
43
43
  "typed-emitter": "^2.1.0",
44
44
  "uint8arrays": "3.0.0",
45
45
  "zod": "^3.21.4",
46
- "@atproto/api": "^0.12.12",
47
46
  "@atproto/aws": "^0.2.0",
48
47
  "@atproto/common": "^0.4.0",
48
+ "@atproto/api": "^0.12.12",
49
49
  "@atproto/crypto": "^0.4.0",
50
- "@atproto/identity": "^0.4.0",
51
50
  "@atproto/lexicon": "^0.4.0",
51
+ "@atproto/identity": "^0.4.0",
52
52
  "@atproto/repo": "^0.4.0",
53
53
  "@atproto/syntax": "^0.3.0",
54
54
  "@atproto/xrpc": "^0.5.0",
@@ -0,0 +1,12 @@
1
+ import { Kysely } from 'kysely'
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await db.schema
5
+ .alterTable('app_password')
6
+ .addColumn('privileged', 'integer', (col) => col.notNull().defaultTo(0))
7
+ .execute()
8
+ }
9
+
10
+ export async function down(db: Kysely<unknown>): Promise<void> {
11
+ await db.schema.alterTable('app_password').dropColumn('privileged').execute()
12
+ }
@@ -1,7 +1,9 @@
1
1
  import * as mig001 from './001-init'
2
2
  import * as mig002 from './002-account-deactivation'
3
+ import * as mig003 from './003-privileged-app-passwords'
3
4
 
4
5
  export default {
5
6
  '001': mig001,
6
7
  '002': mig002,
8
+ '003': mig003,
7
9
  }
@@ -3,6 +3,7 @@ export interface AppPassword {
3
3
  name: string
4
4
  passwordScrypt: string
5
5
  createdAt: string
6
+ privileged: 0 | 1
6
7
  }
7
8
 
8
9
  export const tableName = 'app_password'
@@ -5,6 +5,7 @@ import * as ui8 from 'uint8arrays'
5
5
  import * as crypto from '@atproto/crypto'
6
6
  import { AuthScope } from '../../auth-verifier'
7
7
  import { AccountDb } from '../db'
8
+ import { AppPassDescript } from './password'
8
9
 
9
10
  export type AuthToken = {
10
11
  scope: AuthScope
@@ -87,7 +88,7 @@ export const decodeRefreshToken = (jwt: string) => {
87
88
  export const storeRefreshToken = async (
88
89
  db: AccountDb,
89
90
  payload: RefreshToken,
90
- appPasswordName: string | null,
91
+ appPassword: AppPassDescript | null,
91
92
  ) => {
92
93
  const [result] = await db.executeWithRetry(
93
94
  db.db
@@ -95,7 +96,7 @@ export const storeRefreshToken = async (
95
96
  .values({
96
97
  id: payload.jti,
97
98
  did: payload.sub,
98
- appPasswordName,
99
+ appPasswordName: appPassword?.name,
99
100
  expiresAt: new Date(payload.exp * 1000).toISOString(),
100
101
  })
101
102
  .onConflict((oc) => oc.doNothing()), // E.g. when re-granting during a refresh grace period
@@ -104,11 +105,31 @@ export const storeRefreshToken = async (
104
105
  }
105
106
 
106
107
  export const getRefreshToken = async (db: AccountDb, id: string) => {
107
- return db.db
108
+ const res = await db.db
108
109
  .selectFrom('refresh_token')
110
+ .leftJoin(
111
+ 'app_password',
112
+ 'app_password.name',
113
+ 'refresh_token.appPasswordName',
114
+ )
109
115
  .where('id', '=', id)
110
- .selectAll()
116
+ .selectAll('refresh_token')
117
+ .select('app_password.privileged')
111
118
  .executeTakeFirst()
119
+ if (!res) return null
120
+ const { did, expiresAt, appPasswordName, nextId, privileged } = res
121
+ return {
122
+ id,
123
+ did,
124
+ expiresAt,
125
+ nextId,
126
+ appPassword: appPasswordName
127
+ ? {
128
+ name: appPasswordName,
129
+ privileged: privileged === 1 ? true : false,
130
+ }
131
+ : null,
132
+ }
112
133
  }
113
134
 
114
135
  export const deleteExpiredRefreshTokens = async (
@@ -181,4 +202,11 @@ export const getRefreshTokenId = () => {
181
202
  return ui8.toString(crypto.randomBytes(32), 'base64')
182
203
  }
183
204
 
205
+ export const formatScope = (appPassword: AppPassDescript | null): AuthScope => {
206
+ if (!appPassword) return AuthScope.Access
207
+ return appPassword.privileged
208
+ ? AuthScope.AppPassPrivileged
209
+ : AuthScope.AppPass
210
+ }
211
+
184
212
  export class ConcurrentRefreshError extends Error {}
@@ -4,6 +4,11 @@ import * as scrypt from './scrypt'
4
4
  import { AccountDb } from '../db'
5
5
  import { AppPassword } from '../../lexicon/types/com/atproto/server/createAppPassword'
6
6
 
7
+ export type AppPassDescript = {
8
+ name: string
9
+ privileged: boolean
10
+ }
11
+
7
12
  export const verifyAccountPassword = async (
8
13
  db: AccountDb,
9
14
  did: string,
@@ -21,7 +26,7 @@ export const verifyAppPassword = async (
21
26
  db: AccountDb,
22
27
  did: string,
23
28
  password: string,
24
- ): Promise<string | null> => {
29
+ ): Promise<AppPassDescript | null> => {
25
30
  const passwordScrypt = await scrypt.hashAppPassword(did, password)
26
31
  const found = await db.db
27
32
  .selectFrom('app_password')
@@ -29,7 +34,11 @@ export const verifyAppPassword = async (
29
34
  .where('did', '=', did)
30
35
  .where('passwordScrypt', '=', passwordScrypt)
31
36
  .executeTakeFirst()
32
- return found?.name ?? null
37
+ if (!found) return null
38
+ return {
39
+ name: found.name,
40
+ privileged: found.privileged === 1 ? true : false,
41
+ }
33
42
  }
34
43
 
35
44
  export const updateUserPassword = async (
@@ -51,6 +60,7 @@ export const createAppPassword = async (
51
60
  db: AccountDb,
52
61
  did: string,
53
62
  name: string,
63
+ privileged: boolean,
54
64
  ): Promise<AppPassword> => {
55
65
  // create an app password with format:
56
66
  // 1234-abcd-5678-efgh
@@ -71,6 +81,7 @@ export const createAppPassword = async (
71
81
  name,
72
82
  passwordScrypt,
73
83
  createdAt: new Date().toISOString(),
84
+ privileged: privileged ? 1 : 0,
74
85
  })
75
86
  .returningAll(),
76
87
  )
@@ -81,18 +92,25 @@ export const createAppPassword = async (
81
92
  name,
82
93
  password,
83
94
  createdAt: got.createdAt,
95
+ privileged,
84
96
  }
85
97
  }
86
98
 
87
99
  export const listAppPasswords = async (
88
100
  db: AccountDb,
89
101
  did: string,
90
- ): Promise<{ name: string; createdAt: string }[]> => {
91
- return db.db
102
+ ): Promise<{ name: string; createdAt: string; privileged: boolean }[]> => {
103
+ const res = await db.db
92
104
  .selectFrom('app_password')
93
- .select(['name', 'createdAt'])
105
+ .select(['name', 'createdAt', 'privileged'])
94
106
  .where('did', '=', did)
107
+ .orderBy('createdAt', 'desc')
95
108
  .execute()
109
+ return res.map((row) => ({
110
+ name: row.name,
111
+ createdAt: row.createdAt,
112
+ privileged: row.privileged === 1 ? true : false,
113
+ }))
96
114
  }
97
115
 
98
116
  export const deleteAppPassword = async (
@@ -162,15 +162,18 @@ export class AccountManager {
162
162
  // Auth
163
163
  // ----------
164
164
 
165
- async createSession(did: string, appPasswordName: string | null) {
165
+ async createSession(
166
+ did: string,
167
+ appPassword: password.AppPassDescript | null,
168
+ ) {
166
169
  const { accessJwt, refreshJwt } = await auth.createTokens({
167
170
  did,
168
171
  jwtKey: this.jwtKey,
169
172
  serviceDid: this.serviceDid,
170
- scope: appPasswordName === null ? AuthScope.Access : AuthScope.AppPass,
173
+ scope: auth.formatScope(appPassword),
171
174
  })
172
175
  const refreshPayload = auth.decodeRefreshToken(refreshJwt)
173
- await auth.storeRefreshToken(this.db, refreshPayload, appPasswordName)
176
+ await auth.storeRefreshToken(this.db, refreshPayload, appPassword)
174
177
  return { accessJwt, refreshJwt }
175
178
  }
176
179
 
@@ -205,8 +208,7 @@ export class AccountManager {
205
208
  did: token.did,
206
209
  jwtKey: this.jwtKey,
207
210
  serviceDid: this.serviceDid,
208
- scope:
209
- token.appPasswordName === null ? AuthScope.Access : AuthScope.AppPass,
211
+ scope: auth.formatScope(token.appPassword),
210
212
  jti: nextId,
211
213
  })
212
214
 
@@ -219,7 +221,7 @@ export class AccountManager {
219
221
  expiresAt: expiresAt.toISOString(),
220
222
  nextId,
221
223
  }),
222
- auth.storeRefreshToken(dbTxn, refreshPayload, token.appPasswordName),
224
+ auth.storeRefreshToken(dbTxn, refreshPayload, token.appPassword),
223
225
  ]),
224
226
  )
225
227
  } catch (err) {
@@ -238,8 +240,8 @@ export class AccountManager {
238
240
  // Passwords
239
241
  // ----------
240
242
 
241
- async createAppPassword(did: string, name: string) {
242
- return password.createAppPassword(this.db, did, name)
243
+ async createAppPassword(did: string, name: string, privileged: boolean) {
244
+ return password.createAppPassword(this.db, did, name, privileged)
243
245
  }
244
246
 
245
247
  async listAppPasswords(did: string) {
@@ -256,7 +258,7 @@ export class AccountManager {
256
258
  async verifyAppPassword(
257
259
  did: string,
258
260
  passwordStr: string,
259
- ): Promise<string | null> {
261
+ ): Promise<password.AppPassDescript | null> {
260
262
  return password.verifyAppPassword(this.db, did, passwordStr)
261
263
  }
262
264
 
@@ -4,85 +4,85 @@ import { pipethrough, pipethroughProcedure } from '../../pipethrough'
4
4
 
5
5
  export default function (server: Server, ctx: AppContext) {
6
6
  server.chat.bsky.actor.deleteAccount({
7
- auth: ctx.authVerifier.accessNotAppPassword,
7
+ auth: ctx.authVerifier.accessAppPassPrivileged,
8
8
  handler: async ({ req, auth }) => {
9
9
  return pipethroughProcedure(ctx, req, auth.credentials.did)
10
10
  },
11
11
  })
12
12
  server.chat.bsky.actor.exportAccountData({
13
- auth: ctx.authVerifier.accessNotAppPassword,
13
+ auth: ctx.authVerifier.accessAppPassPrivileged,
14
14
  handler: ({ req, auth }) => {
15
15
  return pipethrough(ctx, req, auth.credentials.did)
16
16
  },
17
17
  })
18
18
  server.chat.bsky.convo.deleteMessageForSelf({
19
- auth: ctx.authVerifier.accessNotAppPassword,
19
+ auth: ctx.authVerifier.accessAppPassPrivileged,
20
20
  handler: ({ req, auth, input }) => {
21
21
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
22
22
  },
23
23
  })
24
24
  server.chat.bsky.convo.getConvo({
25
- auth: ctx.authVerifier.accessNotAppPassword,
25
+ auth: ctx.authVerifier.accessAppPassPrivileged,
26
26
  handler: ({ req, auth }) => {
27
27
  return pipethrough(ctx, req, auth.credentials.did)
28
28
  },
29
29
  })
30
30
  server.chat.bsky.convo.getConvoForMembers({
31
- auth: ctx.authVerifier.accessNotAppPassword,
31
+ auth: ctx.authVerifier.accessAppPassPrivileged,
32
32
  handler: ({ req, auth }) => {
33
33
  return pipethrough(ctx, req, auth.credentials.did)
34
34
  },
35
35
  })
36
36
  server.chat.bsky.convo.getLog({
37
- auth: ctx.authVerifier.accessNotAppPassword,
37
+ auth: ctx.authVerifier.accessAppPassPrivileged,
38
38
  handler: ({ req, auth }) => {
39
39
  return pipethrough(ctx, req, auth.credentials.did)
40
40
  },
41
41
  })
42
42
  server.chat.bsky.convo.getMessages({
43
- auth: ctx.authVerifier.accessNotAppPassword,
43
+ auth: ctx.authVerifier.accessAppPassPrivileged,
44
44
  handler: ({ req, auth }) => {
45
45
  return pipethrough(ctx, req, auth.credentials.did)
46
46
  },
47
47
  })
48
48
  server.chat.bsky.convo.leaveConvo({
49
- auth: ctx.authVerifier.accessNotAppPassword,
49
+ auth: ctx.authVerifier.accessAppPassPrivileged,
50
50
  handler: ({ req, auth, input }) => {
51
51
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
52
52
  },
53
53
  })
54
54
  server.chat.bsky.convo.listConvos({
55
- auth: ctx.authVerifier.accessNotAppPassword,
55
+ auth: ctx.authVerifier.accessAppPassPrivileged,
56
56
  handler: ({ req, auth }) => {
57
57
  return pipethrough(ctx, req, auth.credentials.did)
58
58
  },
59
59
  })
60
60
  server.chat.bsky.convo.muteConvo({
61
- auth: ctx.authVerifier.accessNotAppPassword,
61
+ auth: ctx.authVerifier.accessAppPassPrivileged,
62
62
  handler: ({ req, auth, input }) => {
63
63
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
64
64
  },
65
65
  })
66
66
  server.chat.bsky.convo.sendMessage({
67
- auth: ctx.authVerifier.accessNotAppPassword,
67
+ auth: ctx.authVerifier.accessAppPassPrivileged,
68
68
  handler: ({ req, auth, input }) => {
69
69
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
70
70
  },
71
71
  })
72
72
  server.chat.bsky.convo.sendMessageBatch({
73
- auth: ctx.authVerifier.accessNotAppPassword,
73
+ auth: ctx.authVerifier.accessAppPassPrivileged,
74
74
  handler: ({ req, auth, input }) => {
75
75
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
76
76
  },
77
77
  })
78
78
  server.chat.bsky.convo.unmuteConvo({
79
- auth: ctx.authVerifier.accessNotAppPassword,
79
+ auth: ctx.authVerifier.accessAppPassPrivileged,
80
80
  handler: ({ req, auth, input }) => {
81
81
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
82
82
  },
83
83
  })
84
84
  server.chat.bsky.convo.updateRead({
85
- auth: ctx.authVerifier.accessNotAppPassword,
85
+ auth: ctx.authVerifier.accessAppPassPrivileged,
86
86
  handler: ({ req, auth, input }) => {
87
87
  return pipethroughProcedure(ctx, req, auth.credentials.did, input.body)
88
88
  },
@@ -5,7 +5,7 @@ import { authPassthru } from '../../../proxy'
5
5
 
6
6
  export default function (server: Server, ctx: AppContext) {
7
7
  server.com.atproto.identity.requestPlcOperationSignature({
8
- auth: ctx.authVerifier.accessNotAppPassword,
8
+ auth: ctx.authVerifier.accessFull,
9
9
  handler: async ({ auth, req }) => {
10
10
  if (ctx.entrywayAgent) {
11
11
  await ctx.entrywayAgent.com.atproto.identity.requestPlcOperationSignature(
@@ -7,7 +7,7 @@ import { authPassthru, resultPassthru } from '../../../proxy'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.identity.signPlcOperation({
10
- auth: ctx.authVerifier.accessNotAppPassword,
10
+ auth: ctx.authVerifier.accessFull,
11
11
  handler: async ({ auth, input, req }) => {
12
12
  if (ctx.entrywayAgent) {
13
13
  return resultPassthru(
@@ -17,7 +17,7 @@ import { BlobRef, LexValue, RepoRecord } from '@atproto/lexicon'
17
17
 
18
18
  export default function (server: Server, ctx: AppContext) {
19
19
  server.com.atproto.repo.importRepo({
20
- auth: ctx.authVerifier.accessNotAppPassword,
20
+ auth: ctx.authVerifier.accessFull,
21
21
  handler: async ({ input, auth }) => {
22
22
  const did = auth.credentials.did
23
23
  if (!ctx.cfg.service.acceptingImports) {
@@ -7,7 +7,7 @@ import { assertValidDidDocumentForService } from './util'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.server.activateAccount({
10
- auth: ctx.authVerifier.accessNotAppPassword,
10
+ auth: ctx.authVerifier.accessFull,
11
11
  handler: async ({ auth }) => {
12
12
  const requester = auth.credentials.did
13
13
 
@@ -4,7 +4,7 @@ import { authPassthru, resultPassthru } from '../../../proxy'
4
4
 
5
5
  export default function (server: Server, ctx: AppContext) {
6
6
  server.com.atproto.server.createAppPassword({
7
- auth: ctx.authVerifier.accessNotAppPassword,
7
+ auth: ctx.authVerifier.accessFull,
8
8
  handler: async ({ auth, input, req }) => {
9
9
  if (ctx.entrywayAgent) {
10
10
  return resultPassthru(
@@ -19,7 +19,9 @@ export default function (server: Server, ctx: AppContext) {
19
19
  const appPassword = await ctx.accountManager.createAppPassword(
20
20
  auth.credentials.did,
21
21
  name,
22
+ input.body.privileged ?? false,
22
23
  )
24
+
23
25
  return {
24
26
  encoding: 'application/json',
25
27
  body: appPassword,
@@ -6,6 +6,7 @@ import { softDeleted } from '../../../../db/util'
6
6
  import { Server } from '../../../../lexicon'
7
7
  import { didDocForSession } from './util'
8
8
  import { authPassthru, resultPassthru } from '../../../proxy'
9
+ import { AppPassDescript } from '../../../../account-manager/helpers/password'
9
10
 
10
11
  export default function (server: Server, ctx: AppContext) {
11
12
  server.com.atproto.server.createSession({
@@ -48,17 +49,17 @@ export default function (server: Server, ctx: AppContext) {
48
49
  throw new AuthRequiredError('Invalid identifier or password')
49
50
  }
50
51
 
51
- let appPasswordName: string | null = null
52
+ let appPassword: AppPassDescript | null = null
52
53
  const validAccountPass = await ctx.accountManager.verifyAccountPassword(
53
54
  user.did,
54
55
  password,
55
56
  )
56
57
  if (!validAccountPass) {
57
- appPasswordName = await ctx.accountManager.verifyAppPassword(
58
+ appPassword = await ctx.accountManager.verifyAppPassword(
58
59
  user.did,
59
60
  password,
60
61
  )
61
- if (appPasswordName === null) {
62
+ if (appPassword === null) {
62
63
  throw new AuthRequiredError('Invalid identifier or password')
63
64
  }
64
65
  }
@@ -71,7 +72,7 @@ export default function (server: Server, ctx: AppContext) {
71
72
  }
72
73
 
73
74
  const [{ accessJwt, refreshJwt }, didDoc] = await Promise.all([
74
- ctx.accountManager.createSession(user.did, appPasswordName),
75
+ ctx.accountManager.createSession(user.did, appPassword),
75
76
  didDocForSession(ctx, user.did),
76
77
  ])
77
78
 
@@ -3,7 +3,7 @@ import AppContext from '../../../../context'
3
3
 
4
4
  export default function (server: Server, ctx: AppContext) {
5
5
  server.com.atproto.server.deactivateAccount({
6
- auth: ctx.authVerifier.accessNotAppPassword,
6
+ auth: ctx.authVerifier.accessFull,
7
7
  handler: async ({ auth, input }) => {
8
8
  const requester = auth.credentials.did
9
9
  await ctx.accountManager.deactivateAccount(
@@ -7,7 +7,7 @@ import { authPassthru, resultPassthru } from '../../../proxy'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.server.getAccountInviteCodes({
10
- auth: ctx.authVerifier.accessNotAppPassword,
10
+ auth: ctx.authVerifier.accessFull,
11
11
  handler: async ({ params, auth, req }) => {
12
12
  if (ctx.entrywayAgent) {
13
13
  return resultPassthru(
@@ -4,7 +4,7 @@ import { Server } from '../../../../lexicon'
4
4
 
5
5
  export default function (server: Server, ctx: AppContext) {
6
6
  server.com.atproto.server.getServiceAuth({
7
- auth: ctx.authVerifier.accessNotAppPassword,
7
+ auth: ctx.authVerifier.accessAppPassPrivileged,
8
8
  handler: async ({ params, auth }) => {
9
9
  const did = auth.credentials.did
10
10
  const keypair = await ctx.actorStore.keypair(did)
@@ -7,7 +7,7 @@ import { UserAlreadyExistsError } from '../../../../account-manager/helpers/acco
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.server.updateEmail({
10
- auth: ctx.authVerifier.accessNotAppPassword,
10
+ auth: ctx.authVerifier.accessFull,
11
11
  handler: async ({ auth, input, req }) => {
12
12
  const did = auth.credentials.did
13
13
  const { token, email } = input.body
@@ -23,6 +23,7 @@ export enum AuthScope {
23
23
  Access = 'com.atproto.access',
24
24
  Refresh = 'com.atproto.refresh',
25
25
  AppPass = 'com.atproto.appPass',
26
+ AppPassPrivileged = 'com.atproto.appPassPrivileged',
26
27
  Deactivated = 'com.atproto.deactivated',
27
28
  }
28
29
 
@@ -117,6 +118,7 @@ export class AuthVerifier {
117
118
  access = (ctx: ReqCtx): Promise<AccessOutput> => {
118
119
  return this.validateAccessToken(ctx.req, [
119
120
  AuthScope.Access,
121
+ AuthScope.AppPassPrivileged,
120
122
  AuthScope.AppPass,
121
123
  ])
122
124
  }
@@ -124,6 +126,7 @@ export class AuthVerifier {
124
126
  accessCheckTakedown = async (ctx: ReqCtx): Promise<AccessOutput> => {
125
127
  const result = await this.validateAccessToken(ctx.req, [
126
128
  AuthScope.Access,
129
+ AuthScope.AppPassPrivileged,
127
130
  AuthScope.AppPass,
128
131
  ])
129
132
  const found = await this.accountManager.getAccount(result.credentials.did, {
@@ -142,14 +145,22 @@ export class AuthVerifier {
142
145
  return result
143
146
  }
144
147
 
145
- accessNotAppPassword = (ctx: ReqCtx): Promise<AccessOutput> => {
148
+ accessFull = (ctx: ReqCtx): Promise<AccessOutput> => {
146
149
  return this.validateAccessToken(ctx.req, [AuthScope.Access])
147
150
  }
148
151
 
152
+ accessAppPassPrivileged = (ctx: ReqCtx): Promise<AccessOutput> => {
153
+ return this.validateAccessToken(ctx.req, [
154
+ AuthScope.Access,
155
+ AuthScope.AppPassPrivileged,
156
+ ])
157
+ }
158
+
149
159
  accessDeactived = (ctx: ReqCtx): Promise<AccessOutput> => {
150
160
  return this.validateAccessToken(ctx.req, [
151
161
  AuthScope.Access,
152
162
  AuthScope.AppPass,
163
+ AuthScope.AppPassPrivileged,
153
164
  AuthScope.Deactivated,
154
165
  ])
155
166
  }
@@ -2052,6 +2052,11 @@ export const schemaDict = {
2052
2052
  description:
2053
2053
  'A short name for the App Password, to help distinguish them.',
2054
2054
  },
2055
+ privileged: {
2056
+ type: 'boolean',
2057
+ description:
2058
+ "If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients.",
2059
+ },
2055
2060
  },
2056
2061
  },
2057
2062
  },
@@ -2082,6 +2087,9 @@ export const schemaDict = {
2082
2087
  type: 'string',
2083
2088
  format: 'datetime',
2084
2089
  },
2090
+ privileged: {
2091
+ type: 'boolean',
2092
+ },
2085
2093
  },
2086
2094
  },
2087
2095
  },
@@ -2629,6 +2637,9 @@ export const schemaDict = {
2629
2637
  type: 'string',
2630
2638
  format: 'datetime',
2631
2639
  },
2640
+ privileged: {
2641
+ type: 'boolean',
2642
+ },
2632
2643
  },
2633
2644
  },
2634
2645
  },