@rudderjs/passport 1.0.0 → 1.1.0

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 (102) hide show
  1. package/dist/Passport.d.ts +93 -0
  2. package/dist/Passport.d.ts.map +1 -1
  3. package/dist/Passport.js +147 -0
  4. package/dist/Passport.js.map +1 -1
  5. package/dist/client-secret.d.ts +12 -0
  6. package/dist/client-secret.d.ts.map +1 -0
  7. package/dist/client-secret.js +63 -0
  8. package/dist/client-secret.js.map +1 -0
  9. package/dist/commands/client.d.ts +21 -0
  10. package/dist/commands/client.d.ts.map +1 -1
  11. package/dist/commands/client.js +27 -2
  12. package/dist/commands/client.js.map +1 -1
  13. package/dist/commands/keys.d.ts +28 -4
  14. package/dist/commands/keys.d.ts.map +1 -1
  15. package/dist/commands/keys.js +34 -4
  16. package/dist/commands/keys.js.map +1 -1
  17. package/dist/commands/purge.d.ts +6 -1
  18. package/dist/commands/purge.d.ts.map +1 -1
  19. package/dist/commands/purge.js +15 -31
  20. package/dist/commands/purge.js.map +1 -1
  21. package/dist/device-code-secret.d.ts +28 -0
  22. package/dist/device-code-secret.d.ts.map +1 -0
  23. package/dist/device-code-secret.js +31 -0
  24. package/dist/device-code-secret.js.map +1 -0
  25. package/dist/grants/authorization-code.d.ts +23 -0
  26. package/dist/grants/authorization-code.d.ts.map +1 -1
  27. package/dist/grants/authorization-code.js +126 -15
  28. package/dist/grants/authorization-code.js.map +1 -1
  29. package/dist/grants/client-credentials.d.ts.map +1 -1
  30. package/dist/grants/client-credentials.js +13 -5
  31. package/dist/grants/client-credentials.js.map +1 -1
  32. package/dist/grants/device-code.d.ts +10 -1
  33. package/dist/grants/device-code.d.ts.map +1 -1
  34. package/dist/grants/device-code.js +41 -10
  35. package/dist/grants/device-code.js.map +1 -1
  36. package/dist/grants/index.d.ts +1 -1
  37. package/dist/grants/index.d.ts.map +1 -1
  38. package/dist/grants/index.js +1 -1
  39. package/dist/grants/index.js.map +1 -1
  40. package/dist/grants/issue-tokens.d.ts +9 -0
  41. package/dist/grants/issue-tokens.d.ts.map +1 -1
  42. package/dist/grants/issue-tokens.js +39 -5
  43. package/dist/grants/issue-tokens.js.map +1 -1
  44. package/dist/grants/refresh-token.d.ts.map +1 -1
  45. package/dist/grants/refresh-token.js +64 -9
  46. package/dist/grants/refresh-token.js.map +1 -1
  47. package/dist/grants/safe-compare.d.ts +19 -0
  48. package/dist/grants/safe-compare.d.ts.map +1 -0
  49. package/dist/grants/safe-compare.js +28 -0
  50. package/dist/grants/safe-compare.js.map +1 -0
  51. package/dist/index.d.ts +27 -6
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +122 -67
  54. package/dist/index.js.map +1 -1
  55. package/dist/middleware/bearer.d.ts.map +1 -1
  56. package/dist/middleware/bearer.js +36 -6
  57. package/dist/middleware/bearer.js.map +1 -1
  58. package/dist/middleware/scope.d.ts +12 -2
  59. package/dist/middleware/scope.d.ts.map +1 -1
  60. package/dist/middleware/scope.js +46 -2
  61. package/dist/middleware/scope.js.map +1 -1
  62. package/dist/models/AccessToken.d.ts +32 -0
  63. package/dist/models/AccessToken.d.ts.map +1 -1
  64. package/dist/models/AccessToken.js +63 -3
  65. package/dist/models/AccessToken.js.map +1 -1
  66. package/dist/models/AuthCode.d.ts +16 -0
  67. package/dist/models/AuthCode.d.ts.map +1 -1
  68. package/dist/models/AuthCode.js +17 -1
  69. package/dist/models/AuthCode.js.map +1 -1
  70. package/dist/models/DeviceCode.d.ts +12 -2
  71. package/dist/models/DeviceCode.d.ts.map +1 -1
  72. package/dist/models/DeviceCode.js +7 -1
  73. package/dist/models/DeviceCode.js.map +1 -1
  74. package/dist/models/OAuthClient.d.ts +4 -0
  75. package/dist/models/OAuthClient.d.ts.map +1 -1
  76. package/dist/models/OAuthClient.js +13 -1
  77. package/dist/models/OAuthClient.js.map +1 -1
  78. package/dist/models/RefreshToken.d.ts +11 -0
  79. package/dist/models/RefreshToken.d.ts.map +1 -1
  80. package/dist/models/RefreshToken.js +12 -2
  81. package/dist/models/RefreshToken.js.map +1 -1
  82. package/dist/models/helpers.d.ts +6 -0
  83. package/dist/models/helpers.d.ts.map +1 -1
  84. package/dist/models/helpers.js +15 -2
  85. package/dist/models/helpers.js.map +1 -1
  86. package/dist/opaque-token.d.ts +32 -0
  87. package/dist/opaque-token.d.ts.map +1 -0
  88. package/dist/opaque-token.js +38 -0
  89. package/dist/opaque-token.js.map +1 -0
  90. package/dist/personal-access-tokens.d.ts.map +1 -1
  91. package/dist/personal-access-tokens.js +48 -10
  92. package/dist/personal-access-tokens.js.map +1 -1
  93. package/dist/routes.d.ts +149 -0
  94. package/dist/routes.d.ts.map +1 -1
  95. package/dist/routes.js +279 -41
  96. package/dist/routes.js.map +1 -1
  97. package/dist/token.d.ts +80 -4
  98. package/dist/token.d.ts.map +1 -1
  99. package/dist/token.js +97 -13
  100. package/dist/token.js.map +1 -1
  101. package/package.json +5 -5
  102. package/schema/passport.prisma +29 -9
@@ -2,10 +2,26 @@ import { Model } from '@rudderjs/orm';
2
2
  export declare class AuthCode extends Model {
3
3
  static table: string;
4
4
  static fillable: string[];
5
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
6
+ static pruneMode: "mass";
7
+ /**
8
+ * Rows safe to remove: expired only. Auth codes are single-use and revoked
9
+ * on exchange, so a revoked-but-unexpired row is still informative for
10
+ * replay-detection diagnostics; we wait for the natural 10-minute TTL
11
+ * before reaping. Mirrors the `passport:purge` predicate.
12
+ */
13
+ static prunable(): import("@rudderjs/contracts").QueryBuilder<AuthCode> & {
14
+ scope(name: string, ...args: unknown[]): import("@rudderjs/contracts").QueryBuilder<AuthCode>;
15
+ withoutGlobalScope(name: string): import("@rudderjs/contracts").QueryBuilder<AuthCode>;
16
+ };
17
+ id: string;
18
+ /** SHA-256 hex of the plaintext authorization code. See `opaque-token.ts`. */
19
+ tokenHash: string;
5
20
  userId: string;
6
21
  clientId: string;
7
22
  revoked: boolean;
8
23
  expiresAt: Date;
24
+ redirectUri: string | null;
9
25
  codeChallenge: string | null;
10
26
  codeChallengeMethod: string | null;
11
27
  /** Parsed scopes array. */
@@ -1 +1 @@
1
- {"version":3,"file":"AuthCode.d.ts","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,QAAS,SAAQ,KAAK;IACjC,OAAgB,KAAK,SAAkB;IAEvC,OAAgB,QAAQ,WAAmG;IAEnH,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAE1C,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,0CAA0C;IAC1C,SAAS,IAAI,OAAO;IAIpB,6BAA6B;IAC7B,MAAM,IAAI,OAAO;CAGlB"}
1
+ {"version":3,"file":"AuthCode.d.ts","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,QAAS,SAAQ,KAAK;IACjC,OAAgB,KAAK,SAAkB;IAOvC,OAAgB,QAAQ,WAAoH;IAE5I,+EAA+E;IAC/E,MAAM,CAAC,SAAS,EAAG,MAAM,CAAS;IAElC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ;;;;IAIP,EAAE,EAAE,MAAM,CAAA;IAClB,8EAA8E;IACtE,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAE1C,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,0CAA0C;IAC1C,SAAS,IAAI,OAAO;IAIpB,6BAA6B;IAC7B,MAAM,IAAI,OAAO;CAGlB"}
@@ -1,7 +1,23 @@
1
1
  import { Model } from '@rudderjs/orm';
2
2
  export class AuthCode extends Model {
3
3
  static table = 'oAuthAuthCode';
4
- static fillable = ['userId', 'clientId', 'scopes', 'revoked', 'expiresAt', 'codeChallenge', 'codeChallengeMethod'];
4
+ // `revoked` is intentionally NOT fillable see AccessToken.ts for the
5
+ // rationale. Auth codes are revoked atomically through
6
+ // `QueryBuilder.where(...).updateAll(...)` in `exchangeAuthCode` (see M3
7
+ // atomic consumption fix), which bypasses mass-assignment, so removing
8
+ // it from fillable is non-breaking.
9
+ static fillable = ['userId', 'clientId', 'tokenHash', 'scopes', 'expiresAt', 'redirectUri', 'codeChallenge', 'codeChallengeMethod'];
10
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
11
+ static pruneMode = 'mass';
12
+ /**
13
+ * Rows safe to remove: expired only. Auth codes are single-use and revoked
14
+ * on exchange, so a revoked-but-unexpired row is still informative for
15
+ * replay-detection diagnostics; we wait for the natural 10-minute TTL
16
+ * before reaping. Mirrors the `passport:purge` predicate.
17
+ */
18
+ static prunable() {
19
+ return this.query().where('expiresAt', '<', new Date());
20
+ }
5
21
  /** Parsed scopes array. */
6
22
  getScopes() {
7
23
  const raw = this['scopes'];
@@ -1 +1 @@
1
- {"version":3,"file":"AuthCode.js","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,MAAM,CAAU,KAAK,GAAG,eAAe,CAAA;IAEvC,MAAM,CAAU,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAA;IAS3H,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0CAA0C;IAC1C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,6BAA6B;IAC7B,MAAM;QACJ,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,CAAA;IACpC,CAAC"}
1
+ {"version":3,"file":"AuthCode.js","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,MAAM,CAAU,KAAK,GAAG,eAAe,CAAA;IAEvC,uEAAuE;IACvE,uDAAuD;IACvD,yEAAyE;IACzE,uEAAuE;IACvE,oCAAoC;IACpC,MAAM,CAAU,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAA;IAE5I,+EAA+E;IAC/E,MAAM,CAAC,SAAS,GAAG,MAAe,CAAA;IAElC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;IACzD,CAAC;IAaD,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0CAA0C;IAC1C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,6BAA6B;IAC7B,MAAM;QACJ,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,CAAA;IACpC,CAAC"}
@@ -2,11 +2,21 @@ import { Model } from '@rudderjs/orm';
2
2
  export declare class DeviceCode extends Model {
3
3
  static table: string;
4
4
  static fillable: string[];
5
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
6
+ static pruneMode: "mass";
7
+ /** Rows safe to remove: expired only. Mirrors the `passport:purge` predicate. */
8
+ static prunable(): import("@rudderjs/contracts").QueryBuilder<DeviceCode> & {
9
+ scope(name: string, ...args: unknown[]): import("@rudderjs/contracts").QueryBuilder<DeviceCode>;
10
+ withoutGlobalScope(name: string): import("@rudderjs/contracts").QueryBuilder<DeviceCode>;
11
+ };
12
+ id: string;
5
13
  clientId: string;
6
- userCode: string;
7
- deviceCode: string;
14
+ userCodeHash: string;
15
+ deviceCodeHash: string;
8
16
  userId: string | null;
9
17
  approved: boolean | null;
18
+ /** Current polling interval in seconds (RFC 8628 §3.5). Escalates on slow_down. */
19
+ interval: number;
10
20
  expiresAt: Date;
11
21
  lastPolledAt: Date | null;
12
22
  /** Parsed scopes array. */
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceCode.d.ts","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,UAAW,SAAQ,KAAK;IACnC,OAAgB,KAAK,SAAoB;IAEzC,OAAgB,QAAQ,WAAsG;IAEtH,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,EAAE,IAAI,GAAG,IAAI,CAAA;IAEjC,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,4CAA4C;IAC5C,SAAS,IAAI,OAAO;IAIpB,iDAAiD;IACjD,UAAU,IAAI,OAAO;IAIrB,+CAA+C;IAC/C,QAAQ,IAAI,OAAO;IAInB,6CAA6C;IAC7C,SAAS,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"DeviceCode.d.ts","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,UAAW,SAAQ,KAAK;IACnC,OAAgB,KAAK,SAAoB;IAEzC,OAAgB,QAAQ,WAA0H;IAElJ,+EAA+E;IAC/E,MAAM,CAAC,SAAS,EAAG,MAAM,CAAS;IAElC,iFAAiF;IACjF,MAAM,CAAC,QAAQ;;;;IAIP,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAKhB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IAChC,mFAAmF;IAC3E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,EAAE,IAAI,GAAG,IAAI,CAAA;IAEjC,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,4CAA4C;IAC5C,SAAS,IAAI,OAAO;IAIpB,iDAAiD;IACjD,UAAU,IAAI,OAAO;IAIrB,+CAA+C;IAC/C,QAAQ,IAAI,OAAO;IAInB,6CAA6C;IAC7C,SAAS,IAAI,OAAO;CAGrB"}
@@ -1,7 +1,13 @@
1
1
  import { Model } from '@rudderjs/orm';
2
2
  export class DeviceCode extends Model {
3
3
  static table = 'oAuthDeviceCode';
4
- static fillable = ['clientId', 'userCode', 'deviceCode', 'scopes', 'userId', 'approved', 'expiresAt', 'lastPolledAt'];
4
+ static fillable = ['clientId', 'userCodeHash', 'deviceCodeHash', 'scopes', 'userId', 'approved', 'interval', 'expiresAt', 'lastPolledAt'];
5
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
6
+ static pruneMode = 'mass';
7
+ /** Rows safe to remove: expired only. Mirrors the `passport:purge` predicate. */
8
+ static prunable() {
9
+ return this.query().where('expiresAt', '<', new Date());
10
+ }
5
11
  /** Parsed scopes array. */
6
12
  getScopes() {
7
13
  const raw = this['scopes'];
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceCode.js","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,MAAM,CAAU,KAAK,GAAG,iBAAiB,CAAA;IAEzC,MAAM,CAAU,QAAQ,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;IAU9H,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,4CAA4C;IAC5C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,iDAAiD;IACjD,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC;IAED,+CAA+C;IAC/C,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAA;IAChC,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC"}
1
+ {"version":3,"file":"DeviceCode.js","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,MAAM,CAAU,KAAK,GAAG,iBAAiB,CAAA;IAEzC,MAAM,CAAU,QAAQ,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;IAElJ,+EAA+E;IAC/E,MAAM,CAAC,SAAS,GAAG,MAAe,CAAA;IAElC,iFAAiF;IACjF,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;IACzD,CAAC;IAiBD,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,4CAA4C;IAC5C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,iDAAiD;IACjD,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC;IAED,+CAA+C;IAC/C,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAA;IAChC,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC"}
@@ -2,7 +2,11 @@ import { Model } from '@rudderjs/orm';
2
2
  export declare class OAuthClient extends Model {
3
3
  static table: string;
4
4
  static fillable: string[];
5
+ id: string;
5
6
  secret: string | null;
7
+ redirectUris: string[];
8
+ grantTypes: string[];
9
+ scopes: string[];
6
10
  name: string;
7
11
  confidential: boolean;
8
12
  revoked: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClient.d.ts","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAU,MAAM,eAAe,CAAA;AAE7C,qBAAa,WAAY,SAAQ,KAAK;IACpC,OAAgB,KAAK,SAAgB;IAErC,OAAgB,QAAQ,WAA6E;IAG7F,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAErB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAExB,4BAA4B;IAC5B,eAAe,IAAI,MAAM,EAAE;IAM3B,0BAA0B;IAC1B,aAAa,IAAI,MAAM,EAAE;IAMzB,qBAAqB;IACrB,SAAS,IAAI,MAAM,EAAE;IAMrB,sDAAsD;IACtD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,6DAA6D;IAC7D,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC,sEAAsE;IACtE,QAAQ,IAAI,OAAO;CAGpB"}
1
+ {"version":3,"file":"OAuthClient.d.ts","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAA;AAEnD,qBAAa,WAAY,SAAQ,KAAK;IACpC,OAAgB,KAAK,SAAgB;IAErC,OAAgB,QAAQ,WAA6E;IAE7F,EAAE,EAAE,MAAM,CAAA;IAGV,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IASrB,YAAY,EAAE,MAAM,EAAE,CAAA;IAGtB,UAAU,EAAE,MAAM,EAAE,CAAA;IAGpB,MAAM,EAAE,MAAM,EAAE,CAAA;IAEhB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAExB,4BAA4B;IAC5B,eAAe,IAAI,MAAM,EAAE;IAM3B,0BAA0B;IAC1B,aAAa,IAAI,MAAM,EAAE;IAMzB,qBAAqB;IACrB,SAAS,IAAI,MAAM,EAAE;IAMrB,sDAAsD;IACtD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,6DAA6D;IAC7D,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC,sEAAsE;IACtE,QAAQ,IAAI,OAAO;CAGpB"}
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { Model, Hidden } from '@rudderjs/orm';
10
+ import { Model, Hidden, Cast } from '@rudderjs/orm';
11
11
  export class OAuthClient extends Model {
12
12
  static table = 'oAuthClient';
13
13
  static fillable = ['name', 'secret', 'redirectUris', 'grantTypes', 'scopes', 'confidential'];
@@ -49,4 +49,16 @@ __decorate([
49
49
  Hidden,
50
50
  __metadata("design:type", Object)
51
51
  ], OAuthClient.prototype, "secret", void 0);
52
+ __decorate([
53
+ Cast('json'),
54
+ __metadata("design:type", Array)
55
+ ], OAuthClient.prototype, "redirectUris", void 0);
56
+ __decorate([
57
+ Cast('json'),
58
+ __metadata("design:type", Array)
59
+ ], OAuthClient.prototype, "grantTypes", void 0);
60
+ __decorate([
61
+ Cast('json'),
62
+ __metadata("design:type", Array)
63
+ ], OAuthClient.prototype, "scopes", void 0);
52
64
  //# sourceMappingURL=OAuthClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,MAAM,CAAU,KAAK,GAAG,aAAa,CAAA;IAErC,MAAM,CAAU,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;IASrG,4BAA4B;IAC5B,eAAe;QACb,MAAM,GAAG,GAAI,IAA2C,CAAC,cAAc,CAAC,CAAA;QACxE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0BAA0B;IAC1B,aAAa;QACX,MAAM,GAAG,GAAI,IAA2C,CAAC,YAAY,CAAC,CAAA;QACtE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,qBAAqB;IACrB,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,sDAAsD;IACtD,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5C,CAAC;IAED,6DAA6D;IAC7D,cAAc,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAC7C,CAAC;IAED,sEAAsE;IACtE,QAAQ;QACN,OAAO,CAAC,IAAI,CAAC,YAAY,CAAA;IAC3B,CAAC;;AAxCO;IADP,MAAM;;2CACsB"}
1
+ {"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEnD,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,MAAM,CAAU,KAAK,GAAG,aAAa,CAAA;IAErC,MAAM,CAAU,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;IA0BrG,4BAA4B;IAC5B,eAAe;QACb,MAAM,GAAG,GAAI,IAA2C,CAAC,cAAc,CAAC,CAAA;QACxE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0BAA0B;IAC1B,aAAa;QACX,MAAM,GAAG,GAAI,IAA2C,CAAC,YAAY,CAAC,CAAA;QACtE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,qBAAqB;IACrB,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,sDAAsD;IACtD,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5C,CAAC;IAED,6DAA6D;IAC7D,cAAc,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAC7C,CAAC;IAED,sEAAsE;IACtE,QAAQ;QACN,OAAO,CAAC,IAAI,CAAC,YAAY,CAAA;IAC3B,CAAC;;AAvDO;IADP,MAAM;;2CACsB;AASrB;IADP,IAAI,CAAC,MAAM,CAAC;;iDACiB;AAGtB;IADP,IAAI,CAAC,MAAM,CAAC;;+CACe;AAGpB;IADP,IAAI,CAAC,MAAM,CAAC;;2CACW"}
@@ -2,7 +2,18 @@ import { Model } from '@rudderjs/orm';
2
2
  export declare class RefreshToken extends Model {
3
3
  static table: string;
4
4
  static fillable: string[];
5
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
6
+ static pruneMode: "mass";
7
+ /** Rows safe to remove: expired OR revoked. Same predicate as `passport:purge`. */
8
+ static prunable(): import("@rudderjs/contracts").QueryBuilder<RefreshToken> & {
9
+ scope(name: string, ...args: unknown[]): import("@rudderjs/contracts").QueryBuilder<RefreshToken>;
10
+ withoutGlobalScope(name: string): import("@rudderjs/contracts").QueryBuilder<RefreshToken>;
11
+ };
12
+ id: string;
5
13
  accessTokenId: string;
14
+ /** SHA-256 hex of the plaintext refresh token. See `opaque-token.ts`. */
15
+ tokenHash: string;
16
+ familyId: string | null;
6
17
  revoked: boolean;
7
18
  expiresAt: Date;
8
19
  /** Revoke this refresh token. */
@@ -1 +1 @@
1
- {"version":3,"file":"RefreshToken.d.ts","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,YAAa,SAAQ,KAAK;IACrC,OAAgB,KAAK,SAAsB;IAE3C,OAAgB,QAAQ,WAA4C;IAE5D,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IAEvB,iCAAiC;IAC3B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,sCAAsC;IACtC,SAAS,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"RefreshToken.d.ts","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,YAAa,SAAQ,KAAK;IACrC,OAAgB,KAAK,SAAsB;IAI3C,OAAgB,QAAQ,WAA0D;IAElF,+EAA+E;IAC/E,MAAM,CAAC,SAAS,EAAG,MAAM,CAAS;IAElC,mFAAmF;IACnF,MAAM,CAAC,QAAQ;;;;IAMP,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,EAAE,MAAM,CAAA;IAC7B,yEAAyE;IACjE,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IAEvB,iCAAiC;IAC3B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,sCAAsC;IACtC,SAAS,IAAI,OAAO;CAGrB"}
@@ -1,11 +1,21 @@
1
1
  import { Model } from '@rudderjs/orm';
2
2
  export class RefreshToken extends Model {
3
3
  static table = 'oAuthRefreshToken';
4
- static fillable = ['accessTokenId', 'revoked', 'expiresAt'];
4
+ // `revoked` is intentionally NOT fillable see AccessToken.ts for the
5
+ // rationale. Lifecycle flips happen through `revoke()` or `forceFill`.
6
+ static fillable = ['accessTokenId', 'tokenHash', 'familyId', 'expiresAt'];
7
+ /** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
8
+ static pruneMode = 'mass';
9
+ /** Rows safe to remove: expired OR revoked. Same predicate as `passport:purge`. */
10
+ static prunable() {
11
+ return this.query()
12
+ .where('expiresAt', '<', new Date())
13
+ .orWhere('revoked', true);
14
+ }
5
15
  /** Revoke this refresh token. */
6
16
  async revoke() {
7
17
  this.revoked = true;
8
- await this.constructor.update(this.id, { revoked: true });
18
+ await this.save();
9
19
  }
10
20
  /** Whether this token has expired. */
11
21
  isExpired() {
@@ -1 +1 @@
1
- {"version":3,"file":"RefreshToken.js","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,MAAM,CAAU,KAAK,GAAG,mBAAmB,CAAA;IAE3C,MAAM,CAAU,QAAQ,GAAG,CAAC,eAAe,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAMpE,iCAAiC;IACjC,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,MAAO,IAAI,CAAC,WAAmC,CAAC,MAAM,CAAE,IAAY,CAAC,EAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAA;IAC9G,CAAC;IAED,sCAAsC;IACtC,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC"}
1
+ {"version":3,"file":"RefreshToken.js","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,MAAM,CAAU,KAAK,GAAG,mBAAmB,CAAA;IAE3C,uEAAuE;IACvE,uEAAuE;IACvE,MAAM,CAAU,QAAQ,GAAG,CAAC,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAA;IAElF,+EAA+E;IAC/E,MAAM,CAAC,SAAS,GAAG,MAAe,CAAA;IAElC,mFAAmF;IACnF,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,EAAE;aAChB,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;aACnC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAUD,iCAAiC;IACjC,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;IACnB,CAAC;IAED,sCAAsC;IACtC,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC"}
@@ -20,17 +20,23 @@ export interface AccessTokenRecord {
20
20
  }
21
21
  export interface RefreshTokenRecord {
22
22
  id: string;
23
+ /** SHA-256 hex of the plaintext refresh token. */
24
+ tokenHash: string;
23
25
  accessTokenId: string;
26
+ familyId: string | null;
24
27
  revoked: boolean;
25
28
  expiresAt: Date;
26
29
  }
27
30
  export interface AuthCodeRecord {
28
31
  id: string;
32
+ /** SHA-256 hex of the plaintext authorization code. */
33
+ tokenHash: string;
29
34
  userId: string;
30
35
  clientId: string;
31
36
  scopes: string;
32
37
  revoked: boolean;
33
38
  expiresAt: Date;
39
+ redirectUri: string | null;
34
40
  codeChallenge: string | null;
35
41
  codeChallengeMethod: string | null;
36
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAY,MAAM,CAAA;IACpB,IAAI,EAAU,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAI,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAO,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAS,MAAM,CAAA;IACjB,MAAM,EAAK,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAG,MAAM,CAAA;IACjB,IAAI,EAAO,MAAM,GAAG,IAAI,CAAA;IACxB,MAAM,EAAK,MAAM,CAAA;IACjB,OAAO,EAAI,OAAO,CAAA;IAClB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAa,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAQ,OAAO,CAAA;IACtB,SAAS,EAAM,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAmB,MAAM,CAAA;IAC3B,MAAM,EAAe,MAAM,CAAA;IAC3B,QAAQ,EAAa,MAAM,CAAA;IAC3B,MAAM,EAAe,MAAM,CAAA;IAC3B,OAAO,EAAc,OAAO,CAAA;IAC5B,SAAS,EAAY,IAAI,CAAA;IACzB,aAAa,EAAQ,MAAM,GAAG,IAAI,CAAA;IAClC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAY,MAAM,CAAA;IACpB,QAAQ,EAAM,MAAM,CAAA;IACpB,QAAQ,EAAM,MAAM,CAAA;IACpB,UAAU,EAAI,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAM,OAAO,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAK,IAAI,CAAA;IAClB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAA;CAC1B;AAcD,eAAO,MAAM,aAAa;yBACH,iBAAiB,KAAG,MAAM,EAAE;uBAC5B,iBAAiB,KAAG,MAAM,EAAE;mBAC5B,iBAAiB,KAAG,MAAM,EAAE;sBAE9B,iBAAiB,QAAQ,MAAM,KAAG,OAAO;wBACxC,iBAAiB,OAAO,MAAM,KAAG,OAAO;kBAE9C,iBAAiB,KAAG,OAAO;CAC1C,CAAA;AAID,eAAO,MAAM,kBAAkB;mBACd,iBAAiB,KAAG,MAAM,EAAE;aAElC,iBAAiB,SAAS,MAAM,KAAG,OAAO;mBAKpC,iBAAiB,KAAG,OAAO;iBAC3B,iBAAiB,KAAG,OAAO;CAC3C,CAAA;AAID,eAAO,MAAM,mBAAmB;mBACf,kBAAkB,KAAG,OAAO;CAC5C,CAAA;AAID,eAAO,MAAM,eAAe;mBACX,cAAc,KAAG,MAAM,EAAE;mBACzB,cAAc,KAAG,OAAO;gBACxB,cAAc,KAAG,OAAO;CACxC,CAAA;AAID,eAAO,MAAM,iBAAiB;mBACZ,gBAAgB,KAAG,MAAM,EAAE;mBAC3B,gBAAgB,KAAG,OAAO;oBAC1B,gBAAgB,KAAG,OAAO;kBAC1B,gBAAgB,KAAG,OAAO;mBAC1B,gBAAgB,KAAG,OAAO;CAC3C,CAAA"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAY,MAAM,CAAA;IACpB,IAAI,EAAU,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAI,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAO,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAS,MAAM,CAAA;IACjB,MAAM,EAAK,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAG,MAAM,CAAA;IACjB,IAAI,EAAO,MAAM,GAAG,IAAI,CAAA;IACxB,MAAM,EAAK,MAAM,CAAA;IACjB,OAAO,EAAI,OAAO,CAAA;IAClB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAa,MAAM,CAAA;IACrB,kDAAkD;IAClD,SAAS,EAAM,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAO,MAAM,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAQ,OAAO,CAAA;IACtB,SAAS,EAAM,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAmB,MAAM,CAAA;IAC3B,uDAAuD;IACvD,SAAS,EAAY,MAAM,CAAA;IAC3B,MAAM,EAAe,MAAM,CAAA;IAC3B,QAAQ,EAAa,MAAM,CAAA;IAC3B,MAAM,EAAe,MAAM,CAAA;IAC3B,OAAO,EAAc,OAAO,CAAA;IAC5B,SAAS,EAAY,IAAI,CAAA;IACzB,WAAW,EAAU,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,EAAQ,MAAM,GAAG,IAAI,CAAA;IAClC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAY,MAAM,CAAA;IACpB,QAAQ,EAAM,MAAM,CAAA;IACpB,QAAQ,EAAM,MAAM,CAAA;IACpB,UAAU,EAAI,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,CAAA;IACpB,MAAM,EAAQ,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAM,OAAO,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAK,IAAI,CAAA;IAClB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAA;CAC1B;AA0BD,eAAO,MAAM,aAAa;yBACH,iBAAiB,KAAG,MAAM,EAAE;uBAC5B,iBAAiB,KAAG,MAAM,EAAE;mBAC5B,iBAAiB,KAAG,MAAM,EAAE;sBAE9B,iBAAiB,QAAQ,MAAM,KAAG,OAAO;wBACxC,iBAAiB,OAAO,MAAM,KAAG,OAAO;kBAE9C,iBAAiB,KAAG,OAAO;CAC1C,CAAA;AAID,eAAO,MAAM,kBAAkB;mBACd,iBAAiB,KAAG,MAAM,EAAE;aAElC,iBAAiB,SAAS,MAAM,KAAG,OAAO;mBAKpC,iBAAiB,KAAG,OAAO;iBAC3B,iBAAiB,KAAG,OAAO;CAC3C,CAAA;AAID,eAAO,MAAM,mBAAmB;mBACf,kBAAkB,KAAG,OAAO;CAC5C,CAAA;AAID,eAAO,MAAM,eAAe;mBACX,cAAc,KAAG,MAAM,EAAE;mBACzB,cAAc,KAAG,OAAO;gBACxB,cAAc,KAAG,OAAO;CACxC,CAAA;AAID,eAAO,MAAM,iBAAiB;mBACZ,gBAAgB,KAAG,MAAM,EAAE;mBAC3B,gBAAgB,KAAG,OAAO;oBAC1B,gBAAgB,KAAG,OAAO;kBAC1B,gBAAgB,KAAG,OAAO;mBAC1B,gBAAgB,KAAG,OAAO;CAC3C,CAAA"}
@@ -1,4 +1,10 @@
1
- // Helper functions that operate on raw OAuth records (ORM returns plain objects, not instances).
1
+ // Helper functions that operate on plain OAuth records both Model instances
2
+ // (returned from the ORM read paths since PR #111 on 2026-04-30) and raw rows
3
+ // (cached JSON, fixtures, adapter-level snapshots). The Model classes expose
4
+ // equivalent instance methods (`OAuthClient.getRedirectUris()`,
5
+ // `AccessToken.can()`, etc.) and prefer those when you already hold a Model
6
+ // instance — these helpers stay around for the raw-record case and to keep
7
+ // the grants' read paths legible while they migrate over.
2
8
  // ─── Parsing helpers ──────────────────────────────────────
3
9
  function parseJsonArray(raw) {
4
10
  if (Array.isArray(raw))
@@ -7,7 +13,14 @@ function parseJsonArray(raw) {
7
13
  try {
8
14
  return JSON.parse(raw);
9
15
  }
10
- catch {
16
+ catch (err) {
17
+ // Fail-closed: corrupt JSON returns []. We log the failure (instead of
18
+ // swallowing silently) so persistent corruption isn't a mystery later —
19
+ // a token row whose `scopes` doesn't parse silently authorizes nothing,
20
+ // which is the safe default but produces confusing 403s in production.
21
+ const preview = raw.length > 64 ? `${raw.slice(0, 64)}…` : raw;
22
+ console.warn(`[@rudderjs/passport] Failed to parse JSON-array column from OAuth record. ` +
23
+ `Returning [] (fail-closed). Raw value: ${JSON.stringify(preview)}. Error: ${err.message}`);
11
24
  return [];
12
25
  }
13
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Opaque-token generation + hashing for `oauth_refresh_tokens` and
3
+ * `oauth_auth_codes`.
4
+ *
5
+ * Both tables store the credential as `tokenHash` (SHA-256 of the plaintext)
6
+ * with the plaintext returned to the client only once at issuance and never
7
+ * persisted. A DB read leak yields hashes, not usable bearer credentials.
8
+ *
9
+ * Same plain-SHA-256 reasoning as `device-code-secret.ts`:
10
+ *
11
+ * - The plaintext is `randomBytes(48).toString('base64url')` — 384 bits CSPRNG.
12
+ * Already unguessable per request; pepper would buy nothing.
13
+ * - The threat being mitigated is **DB read leak**: a `SELECT *` on
14
+ * `oauth_refresh_tokens` / `oauth_auth_codes` should not yield credentials
15
+ * that an attacker can replay against `/oauth/token`.
16
+ * - Constant-time compare is implicit via the `@unique` index lookup —
17
+ * the application layer hashes the inbound plaintext, then equality-matches
18
+ * on the indexed column. The B-tree probe on a 64-char hash is not a
19
+ * useful timing side channel.
20
+ *
21
+ * This helper is intentionally separate from `device-code-secret.ts` because
22
+ * the threat-model commentary differs (device codes have a 15-minute TTL +
23
+ * api-group rate limiting; refresh tokens are long-lived). Keeping the docs
24
+ * close to the use site avoids confusing future readers about which surface
25
+ * this applies to.
26
+ *
27
+ * Lazy-loads `node:crypto` so the package stays importable from non-Node
28
+ * runtimes that never reach this code path.
29
+ */
30
+ export declare function newOpaqueToken(): Promise<string>;
31
+ export declare function hashOpaqueToken(plaintext: string): Promise<string>;
32
+ //# sourceMappingURL=opaque-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opaque-token.d.ts","sourceRoot":"","sources":["../src/opaque-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAGtD;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxE"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Opaque-token generation + hashing for `oauth_refresh_tokens` and
3
+ * `oauth_auth_codes`.
4
+ *
5
+ * Both tables store the credential as `tokenHash` (SHA-256 of the plaintext)
6
+ * with the plaintext returned to the client only once at issuance and never
7
+ * persisted. A DB read leak yields hashes, not usable bearer credentials.
8
+ *
9
+ * Same plain-SHA-256 reasoning as `device-code-secret.ts`:
10
+ *
11
+ * - The plaintext is `randomBytes(48).toString('base64url')` — 384 bits CSPRNG.
12
+ * Already unguessable per request; pepper would buy nothing.
13
+ * - The threat being mitigated is **DB read leak**: a `SELECT *` on
14
+ * `oauth_refresh_tokens` / `oauth_auth_codes` should not yield credentials
15
+ * that an attacker can replay against `/oauth/token`.
16
+ * - Constant-time compare is implicit via the `@unique` index lookup —
17
+ * the application layer hashes the inbound plaintext, then equality-matches
18
+ * on the indexed column. The B-tree probe on a 64-char hash is not a
19
+ * useful timing side channel.
20
+ *
21
+ * This helper is intentionally separate from `device-code-secret.ts` because
22
+ * the threat-model commentary differs (device codes have a 15-minute TTL +
23
+ * api-group rate limiting; refresh tokens are long-lived). Keeping the docs
24
+ * close to the use site avoids confusing future readers about which surface
25
+ * this applies to.
26
+ *
27
+ * Lazy-loads `node:crypto` so the package stays importable from non-Node
28
+ * runtimes that never reach this code path.
29
+ */
30
+ export async function newOpaqueToken() {
31
+ const { randomBytes } = await import('node:crypto');
32
+ return randomBytes(48).toString('base64url');
33
+ }
34
+ export async function hashOpaqueToken(plaintext) {
35
+ const { createHash } = await import('node:crypto');
36
+ return createHash('sha256').update(plaintext).digest('hex');
37
+ }
38
+ //# sourceMappingURL=opaque-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opaque-token.js","sourceRoot":"","sources":["../src/opaque-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IACnD,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"personal-access-tokens.d.ts","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAO1D,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,KAAK,EAAE,WAAW,CAAA;IAClB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAA;CACvB;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnG,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IAChC,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACzE,IAAI,EAAE,CAAC,GACN,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,oBAAoB,CAAC,CAkEpD;AAoCD,wDAAwD;AACxD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
1
+ {"version":3,"file":"personal-access-tokens.d.ts","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAO1D,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,KAAK,EAAE,WAAW,CAAA;IAClB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAA;CACvB;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnG,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IAChC,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACzE,IAAI,EAAE,CAAC,GACN,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,oBAAoB,CAAC,CAwGpD;AAoCD,wDAAwD;AACxD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
@@ -32,27 +32,65 @@ export function HasApiTokens(Base) {
32
32
  });
33
33
  return { token: tokenRecord, plainTextToken: jwt };
34
34
  }
35
- /** Get all personal access tokens for this user. */
35
+ /**
36
+ * Get the **personal access** tokens for this user.
37
+ *
38
+ * Filters on both `userId` AND `clientId === personalAccessClient.id`,
39
+ * so OAuth-app session tokens (issued by third-party clients on this
40
+ * user's behalf) are excluded. The previous implementation returned
41
+ * every access-token row owned by the user — a UI listing personal
42
+ * tokens would surface unrelated third-party authorizations and a
43
+ * "log out all my dev tokens" button would have revoked them.
44
+ *
45
+ * Returns AccessToken Model instances. `AccessToken.toJSON()` hides
46
+ * `userId` and `clientId` by default, so exposing the result over an
47
+ * API leaks only `id`, `name`, `scopes`, `revoked`, `expiresAt`. If
48
+ * you need ownership info on a privileged route, opt in via
49
+ * `t.makeVisible(['userId', 'clientId'])` per token.
50
+ *
51
+ * Consumers MUST keep this method scoped to the authenticated user —
52
+ * exposing other users' tokens via this same accessor (e.g. an admin
53
+ * endpoint that takes a `userId` parameter) bypasses the per-user scope
54
+ * implicit in the mixin.
55
+ */
36
56
  async tokens() {
37
57
  const userId = this.id;
38
58
  const AccessTokenCls = await Passport.tokenModel();
39
- return AccessTokenCls.where('userId', userId).get();
59
+ const personalClientId = await getPersonalAccessClientId();
60
+ return AccessTokenCls
61
+ .where('userId', userId)
62
+ .where('clientId', personalClientId)
63
+ .get();
40
64
  }
41
- /** Revoke all personal access tokens for this user. */
65
+ /**
66
+ * Revoke this user's **personal access** tokens.
67
+ *
68
+ * Filters on the personal-access client (same scope as `tokens()`), so
69
+ * third-party OAuth app authorizations are not collateral. Returns the
70
+ * count of rows that flipped `revoked = true` — already-revoked rows
71
+ * are skipped by the inner `.where('revoked', false)` predicate.
72
+ */
42
73
  async revokeAllTokens() {
74
+ // Single bulk QueryBuilder.updateAll() — bypasses mass-assignment
75
+ // (`revoked` is no longer in `fillable`) and replaces the prior
76
+ // read-then-N+1-update loop with one round-trip.
77
+ const userId = this.id;
43
78
  const AccessTokenCls = await Passport.tokenModel();
44
- const tokens = await this.tokens();
45
- for (const t of tokens) {
46
- await AccessTokenCls.update(t.id, { revoked: true });
47
- }
48
- return tokens.length;
79
+ const personalClientId = await getPersonalAccessClientId();
80
+ return AccessTokenCls
81
+ .where('userId', userId)
82
+ .where('clientId', personalClientId)
83
+ .where('revoked', false)
84
+ .updateAll({ revoked: true });
49
85
  }
50
86
  /**
51
87
  * Check if this user's current token has a specific scope.
52
- * Only works inside a request that went through BearerMiddleware.
88
+ * Only works inside a request that went through BearerMiddleware
89
+ * `__passport_token` is stamped onto the resolved user model and
90
+ * propagates onto `req.user` via the plain-copy step.
53
91
  */
54
92
  tokenCan(scope) {
55
- const token = this.__currentToken;
93
+ const token = this.__passport_token;
56
94
  if (!token)
57
95
  return false;
58
96
  return accessTokenHelpers.can(token, scope);
@@ -1 +1 @@
1
- {"version":3,"file":"personal-access-tokens.js","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAiCxC,MAAM,UAAU,YAAY,CAC1B,IAAO;IAEP,MAAe,aAAc,SAAQ,IAAI;QACvC;;;WAGG;QACH,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,SAAmB,CAAC,GAAG,CAAC,EAAE,WAAoB;YAC5E,MAAM,MAAM,GAAI,IAAY,CAAC,EAAY,CAAA;YACzC,MAAM,QAAQ,GAAG,WAAW,IAAI,QAAQ,CAAC,qBAAqB,EAAE,CAAA;YAChE,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAA;YAEjD,mDAAmD;YACnD,MAAM,QAAQ,GAAG,MAAM,yBAAyB,EAAE,CAAA;YAElD,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAA;YAClD,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC;gBAC9C,MAAM;gBACN,QAAQ;gBACR,IAAI;gBACJ,MAAM,EAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBACjC,OAAO,EAAI,KAAK;gBAChB,SAAS;aACiB,CAAgB,CAAA;YAE5C,MAAM,OAAO,GAAI,WAAmB,CAAC,EAAY,CAAA;YAEjD,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC;gBAC5B,OAAO;gBACP,MAAM;gBACN,QAAQ;gBACR,MAAM;gBACN,SAAS;aACV,CAAC,CAAA;YAEF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,CAAA;QACpD,CAAC;QAED,oDAAoD;QACpD,KAAK,CAAC,MAAM;YACV,MAAM,MAAM,GAAI,IAAY,CAAC,EAAY,CAAA;YACzC,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAA;YAClD,OAAO,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,GAAG,EAA4B,CAAA;QAC/E,CAAC;QAED,uDAAuD;QACvD,KAAK,CAAC,eAAe;YACnB,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAA;YAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;YAClC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,cAAc,CAAC,MAAM,CAAE,CAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAA;YACtE,CAAC;YACD,OAAO,MAAM,CAAC,MAAM,CAAA;QACtB,CAAC;QAED;;;WAGG;QACH,QAAQ,CAAC,KAAa;YACpB,MAAM,KAAK,GAAI,IAAY,CAAC,cAAyC,CAAA;YACrE,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAA;YACxB,OAAO,kBAAkB,CAAC,GAAG,CAAC,KAAY,EAAE,KAAK,CAAC,CAAA;QACpD,CAAC;KACF;IAED,OAAO,aAA8E,CAAA;AACvF,CAAC;AAED,6DAA6D;AAE7D,IAAI,iBAAiB,GAAkB,IAAI,CAAA;AAE3C;;;GAGG;AACH,KAAK,UAAU,yBAAyB;IACtC,IAAI,iBAAiB;QAAE,OAAO,iBAAiB,CAAA;IAE/C,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;IAE9C,2CAA2C;IAC3C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,KAAK,EAAwB,CAAA;IACnG,IAAI,QAAQ,EAAE,CAAC;QACb,iBAAiB,GAAI,QAAgB,CAAC,EAAY,CAAA;QAClD,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED,aAAa;IACb,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC;QACpC,IAAI,EAAU,qBAAqB;QACnC,MAAM,EAAQ,IAAI;QAClB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,UAAU,EAAI,IAAI,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACjD,MAAM,EAAQ,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,YAAY,EAAE,KAAK;KACO,CAAgB,CAAA;IAE5C,iBAAiB,GAAI,MAAc,CAAC,EAAY,CAAA;IAChD,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,yBAAyB;IACvC,iBAAiB,GAAG,IAAI,CAAA;AAC1B,CAAC"}
1
+ {"version":3,"file":"personal-access-tokens.js","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"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"}