@rudderjs/passport 1.1.1 → 1.1.2

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 (67) hide show
  1. package/README.md +96 -15
  2. package/dist/grants/authorization-code.d.ts.map +1 -1
  3. package/dist/grants/authorization-code.js +4 -17
  4. package/dist/grants/authorization-code.js.map +1 -1
  5. package/dist/grants/client-credentials.d.ts.map +1 -1
  6. package/dist/grants/client-credentials.js +4 -17
  7. package/dist/grants/client-credentials.js.map +1 -1
  8. package/dist/grants/device-code.d.ts.map +1 -1
  9. package/dist/grants/device-code.js +2 -1
  10. package/dist/grants/device-code.js.map +1 -1
  11. package/dist/grants/parse-scopes.d.ts +15 -0
  12. package/dist/grants/parse-scopes.d.ts.map +1 -0
  13. package/dist/grants/parse-scopes.js +17 -0
  14. package/dist/grants/parse-scopes.js.map +1 -0
  15. package/dist/grants/refresh-token.d.ts.map +1 -1
  16. package/dist/grants/refresh-token.js +5 -18
  17. package/dist/grants/refresh-token.js.map +1 -1
  18. package/dist/grants/verify-client.d.ts +29 -0
  19. package/dist/grants/verify-client.d.ts.map +1 -0
  20. package/dist/grants/verify-client.js +43 -0
  21. package/dist/grants/verify-client.js.map +1 -0
  22. package/dist/middleware/bearer.d.ts.map +1 -1
  23. package/dist/middleware/bearer.js +98 -103
  24. package/dist/middleware/bearer.js.map +1 -1
  25. package/dist/models/AccessToken.d.ts +3 -3
  26. package/dist/models/AuthCode.d.ts +3 -3
  27. package/dist/models/DeviceCode.d.ts +3 -3
  28. package/dist/models/RefreshToken.d.ts +3 -3
  29. package/dist/models/helpers.d.ts +27 -9
  30. package/dist/models/helpers.d.ts.map +1 -1
  31. package/dist/models/helpers.js +12 -6
  32. package/dist/models/helpers.js.map +1 -1
  33. package/dist/personal-access-tokens.d.ts.map +1 -1
  34. package/dist/personal-access-tokens.js.map +1 -1
  35. package/dist/routes/authorize.d.ts +17 -0
  36. package/dist/routes/authorize.d.ts.map +1 -0
  37. package/dist/routes/authorize.js +107 -0
  38. package/dist/routes/authorize.js.map +1 -0
  39. package/dist/routes/device.d.ts +23 -0
  40. package/dist/routes/device.d.ts.map +1 -0
  41. package/dist/routes/device.js +69 -0
  42. package/dist/routes/device.js.map +1 -0
  43. package/dist/routes/helpers.d.ts +64 -0
  44. package/dist/routes/helpers.d.ts.map +1 -0
  45. package/dist/routes/helpers.js +154 -0
  46. package/dist/routes/helpers.js.map +1 -0
  47. package/dist/routes/revoke.d.ts +16 -0
  48. package/dist/routes/revoke.d.ts.map +1 -0
  49. package/dist/routes/revoke.js +33 -0
  50. package/dist/routes/revoke.js.map +1 -0
  51. package/dist/routes/scopes.d.ts +9 -0
  52. package/dist/routes/scopes.d.ts.map +1 -0
  53. package/dist/routes/scopes.js +13 -0
  54. package/dist/routes/scopes.js.map +1 -0
  55. package/dist/routes/token.d.ts +24 -0
  56. package/dist/routes/token.d.ts.map +1 -0
  57. package/dist/routes/token.js +121 -0
  58. package/dist/routes/token.js.map +1 -0
  59. package/dist/routes/types.d.ts +132 -0
  60. package/dist/routes/types.d.ts.map +1 -0
  61. package/dist/routes/types.js +2 -0
  62. package/dist/routes/types.js.map +1 -0
  63. package/dist/routes.d.ts +2 -120
  64. package/dist/routes.d.ts.map +1 -1
  65. package/dist/routes.js +16 -411
  66. package/dist/routes.js.map +1 -1
  67. package/package.json +3 -3
@@ -0,0 +1,132 @@
1
+ import type { MiddlewareHandler } from '@rudderjs/contracts';
2
+ /**
3
+ * Minimal handler signature. Kept `any`-typed because passport routes are
4
+ * mounted on arbitrary Router implementations (Hono adapter, express-style,
5
+ * test fakes) — pinning a concrete request/response type here would force
6
+ * downstream casts everywhere a handler is implemented.
7
+ */
8
+ export type RouteHandler = (req: any, res: any) => Promise<any> | any;
9
+ /**
10
+ * Minimal Router contract passport's `register*Routes()` functions accept.
11
+ * The `@rudderjs/router` instance satisfies this, as do simple test fakes —
12
+ * we don't import the concrete class here to keep this package usable from
13
+ * apps that bring their own router.
14
+ */
15
+ export interface Router {
16
+ get(path: string, handler: RouteHandler, ...middleware: any[]): void;
17
+ post(path: string, handler: RouteHandler, ...middleware: any[]): void;
18
+ delete(path: string, handler: RouteHandler, ...middleware: any[]): void;
19
+ }
20
+ /** Groups of routes that can be selectively excluded. */
21
+ export type PassportRouteGroup = 'authorize' | 'token' | 'revoke' | 'scopes' | 'device';
22
+ export interface PassportRouteOptions {
23
+ /** Base path for OAuth routes (default: '/oauth') */
24
+ prefix?: string;
25
+ /** Verification URI for device auth (default: '{origin}/oauth/device') */
26
+ verificationUri?: string;
27
+ /** Route groups to skip when registering. */
28
+ except?: PassportRouteGroup[];
29
+ /**
30
+ * Middleware applied to `POST /oauth/token`. The token endpoint is the
31
+ * canonical brute-force target for client_secret guessing — every
32
+ * production app SHOULD mount a per-route rate limiter here.
33
+ *
34
+ * Recommended setup:
35
+ *
36
+ * ```ts
37
+ * import { RateLimit } from '@rudderjs/middleware'
38
+ * import { registerPassportRoutes } from '@rudderjs/passport'
39
+ *
40
+ * registerPassportRoutes(router, {
41
+ * tokenMiddleware: [
42
+ * RateLimit.perMinute(10).by((req) => `${req.ip}:${req.body?.client_id}`),
43
+ * ],
44
+ * })
45
+ * ```
46
+ *
47
+ * The composite key (`ip + client_id`) prevents one noisy client from
48
+ * exhausting the budget for legitimate co-tenants behind a shared NAT,
49
+ * and prevents a single IP from churning through every client_id in the
50
+ * registry. RateLimit also requires a cache provider to be registered —
51
+ * see `@rudderjs/cache`. Without one the middleware silently passes
52
+ * through.
53
+ *
54
+ * Accepts a single handler or an array. Empty / omitted means no
55
+ * additional middleware is applied (the same as before this option
56
+ * existed).
57
+ */
58
+ tokenMiddleware?: MiddlewareHandler | MiddlewareHandler[];
59
+ /**
60
+ * Middleware applied to the consent endpoints — `GET/POST/DELETE
61
+ * /oauth/authorize` and `DELETE /oauth/tokens/:id`. POST /oauth/authorize
62
+ * is the canonical CSRF target (an attacker page that auto-submits a
63
+ * hidden form would mint authorization codes for the victim's logged-in
64
+ * session).
65
+ *
66
+ * Most apps should NOT use this option. The recommended pattern is to
67
+ * mount CSRF on the entire web group from `bootstrap/app.ts`:
68
+ *
69
+ * ```ts
70
+ * .withMiddleware((m) => m.web(CsrfMiddleware()))
71
+ * ```
72
+ *
73
+ * which automatically covers `/oauth/authorize` along with every other
74
+ * state-changing web route. `authorizeMiddleware` is the per-route
75
+ * fallback for apps that do NOT mount CSRF at the group level:
76
+ *
77
+ * ```ts
78
+ * import { CsrfMiddleware } from '@rudderjs/middleware'
79
+ * import { registerPassportWebRoutes } from '@rudderjs/passport'
80
+ *
81
+ * registerPassportWebRoutes(router, {
82
+ * authorizeMiddleware: [CsrfMiddleware()],
83
+ * })
84
+ * ```
85
+ *
86
+ * Don't do both — CsrfMiddleware running twice on the same request
87
+ * emits duplicate `Set-Cookie`s on GETs and runs validation twice on
88
+ * POSTs.
89
+ *
90
+ * Accepts a single handler or an array. Empty / omitted means no
91
+ * additional middleware is applied — the typical case for apps that
92
+ * already CSRF-guard at the group level.
93
+ */
94
+ authorizeMiddleware?: MiddlewareHandler | MiddlewareHandler[];
95
+ /**
96
+ * Middleware applied to the device-flow endpoints — `POST /oauth/device/code`
97
+ * and `POST /oauth/device/approve`. RFC 8628 §5.2 calls for brute-force
98
+ * protection on the user_code surface (8-char alphabet → 32^8 ≈ 1.1×10^12
99
+ * keyspace; per-IP throttling makes exhaustion infeasible).
100
+ *
101
+ * Most apps should NOT need this option. The recommended pattern is to
102
+ * mount a rate limiter on the entire api group from `bootstrap/app.ts`
103
+ * (`withMiddleware((m) => m.api(RateLimit.perMinute(60)))`) — that single
104
+ * hook covers the device endpoints alongside every other api route, and
105
+ * 60/min per-IP is already enough that exhausting the user_code keyspace
106
+ * would take tens of thousands of years.
107
+ *
108
+ * `deviceMiddleware` is the per-route fallback for apps that want a
109
+ * tighter device-specific limit (e.g. `RateLimit.perMinute(5)`) on top of
110
+ * — or in place of — the group default:
111
+ *
112
+ * ```ts
113
+ * import { RateLimit } from '@rudderjs/middleware'
114
+ * import { registerPassportApiRoutes } from '@rudderjs/passport'
115
+ *
116
+ * registerPassportApiRoutes(router, {
117
+ * deviceMiddleware: [RateLimit.perMinute(5).by((req) => req.ip)],
118
+ * })
119
+ * ```
120
+ *
121
+ * Layered limits compose in sequence — group + per-route both run, with
122
+ * the tightest budget winning. Locking individual user_codes after N
123
+ * misses (the stateful half of the original RFC 8628 §5.2 guidance)
124
+ * isn't covered by RateLimit; if you need it, wrap your own middleware.
125
+ *
126
+ * Accepts a single handler or an array. Empty / omitted means no
127
+ * additional middleware is applied — the typical case for apps that
128
+ * already throttle the api group.
129
+ */
130
+ deviceMiddleware?: MiddlewareHandler | MiddlewareHandler[];
131
+ }
132
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routes/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;AAErE;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IACpE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IACrE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;CACxE;AAED,yDAAyD;AACzD,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,CAAA;AAEZ,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,eAAe,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;IACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,mBAAmB,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;IAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;CAC3D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/routes/types.ts"],"names":[],"mappings":""}
package/dist/routes.d.ts CHANGED
@@ -1,122 +1,5 @@
1
- import type { MiddlewareHandler } from '@rudderjs/contracts';
2
- type RouteHandler = (req: any, res: any) => Promise<any> | any;
3
- interface Router {
4
- get(path: string, handler: RouteHandler, ...middleware: any[]): void;
5
- post(path: string, handler: RouteHandler, ...middleware: any[]): void;
6
- delete(path: string, handler: RouteHandler, ...middleware: any[]): void;
7
- }
8
- /** Groups of routes that can be selectively excluded. */
9
- export type PassportRouteGroup = 'authorize' | 'token' | 'revoke' | 'scopes' | 'device';
10
- export interface PassportRouteOptions {
11
- /** Base path for OAuth routes (default: '/oauth') */
12
- prefix?: string;
13
- /** Verification URI for device auth (default: '{origin}/oauth/device') */
14
- verificationUri?: string;
15
- /** Route groups to skip when registering. */
16
- except?: PassportRouteGroup[];
17
- /**
18
- * Middleware applied to `POST /oauth/token`. The token endpoint is the
19
- * canonical brute-force target for client_secret guessing — every
20
- * production app SHOULD mount a per-route rate limiter here.
21
- *
22
- * Recommended setup:
23
- *
24
- * ```ts
25
- * import { RateLimit } from '@rudderjs/middleware'
26
- * import { registerPassportRoutes } from '@rudderjs/passport'
27
- *
28
- * registerPassportRoutes(router, {
29
- * tokenMiddleware: [
30
- * RateLimit.perMinute(10).by((req) => `${req.ip}:${req.body?.client_id}`),
31
- * ],
32
- * })
33
- * ```
34
- *
35
- * The composite key (`ip + client_id`) prevents one noisy client from
36
- * exhausting the budget for legitimate co-tenants behind a shared NAT,
37
- * and prevents a single IP from churning through every client_id in the
38
- * registry. RateLimit also requires a cache provider to be registered —
39
- * see `@rudderjs/cache`. Without one the middleware silently passes
40
- * through.
41
- *
42
- * Accepts a single handler or an array. Empty / omitted means no
43
- * additional middleware is applied (the same as before this option
44
- * existed).
45
- */
46
- tokenMiddleware?: MiddlewareHandler | MiddlewareHandler[];
47
- /**
48
- * Middleware applied to the consent endpoints — `GET/POST/DELETE
49
- * /oauth/authorize` and `DELETE /oauth/tokens/:id`. POST /oauth/authorize
50
- * is the canonical CSRF target (an attacker page that auto-submits a
51
- * hidden form would mint authorization codes for the victim's logged-in
52
- * session).
53
- *
54
- * Most apps should NOT use this option. The recommended pattern is to
55
- * mount CSRF on the entire web group from `bootstrap/app.ts`:
56
- *
57
- * ```ts
58
- * .withMiddleware((m) => m.web(CsrfMiddleware()))
59
- * ```
60
- *
61
- * which automatically covers `/oauth/authorize` along with every other
62
- * state-changing web route. `authorizeMiddleware` is the per-route
63
- * fallback for apps that do NOT mount CSRF at the group level:
64
- *
65
- * ```ts
66
- * import { CsrfMiddleware } from '@rudderjs/middleware'
67
- * import { registerPassportWebRoutes } from '@rudderjs/passport'
68
- *
69
- * registerPassportWebRoutes(router, {
70
- * authorizeMiddleware: [CsrfMiddleware()],
71
- * })
72
- * ```
73
- *
74
- * Don't do both — CsrfMiddleware running twice on the same request
75
- * emits duplicate `Set-Cookie`s on GETs and runs validation twice on
76
- * POSTs.
77
- *
78
- * Accepts a single handler or an array. Empty / omitted means no
79
- * additional middleware is applied — the typical case for apps that
80
- * already CSRF-guard at the group level.
81
- */
82
- authorizeMiddleware?: MiddlewareHandler | MiddlewareHandler[];
83
- /**
84
- * Middleware applied to the device-flow endpoints — `POST /oauth/device/code`
85
- * and `POST /oauth/device/approve`. RFC 8628 §5.2 calls for brute-force
86
- * protection on the user_code surface (8-char alphabet → 32^8 ≈ 1.1×10^12
87
- * keyspace; per-IP throttling makes exhaustion infeasible).
88
- *
89
- * Most apps should NOT need this option. The recommended pattern is to
90
- * mount a rate limiter on the entire api group from `bootstrap/app.ts`
91
- * (`withMiddleware((m) => m.api(RateLimit.perMinute(60)))`) — that single
92
- * hook covers the device endpoints alongside every other api route, and
93
- * 60/min per-IP is already enough that exhausting the user_code keyspace
94
- * would take tens of thousands of years.
95
- *
96
- * `deviceMiddleware` is the per-route fallback for apps that want a
97
- * tighter device-specific limit (e.g. `RateLimit.perMinute(5)`) on top of
98
- * — or in place of — the group default:
99
- *
100
- * ```ts
101
- * import { RateLimit } from '@rudderjs/middleware'
102
- * import { registerPassportApiRoutes } from '@rudderjs/passport'
103
- *
104
- * registerPassportApiRoutes(router, {
105
- * deviceMiddleware: [RateLimit.perMinute(5).by((req) => req.ip)],
106
- * })
107
- * ```
108
- *
109
- * Layered limits compose in sequence — group + per-route both run, with
110
- * the tightest budget winning. Locking individual user_codes after N
111
- * misses (the stateful half of the original RFC 8628 §5.2 guidance)
112
- * isn't covered by RateLimit; if you need it, wrap your own middleware.
113
- *
114
- * Accepts a single handler or an array. Empty / omitted means no
115
- * additional middleware is applied — the typical case for apps that
116
- * already throttle the api group.
117
- */
118
- deviceMiddleware?: MiddlewareHandler | MiddlewareHandler[];
119
- }
1
+ import type { PassportRouteOptions, Router } from './routes/types.js';
2
+ export type { PassportRouteGroup, PassportRouteOptions } from './routes/types.js';
120
3
  /**
121
4
  * Register all Passport OAuth routes on the given router.
122
5
  *
@@ -178,5 +61,4 @@ export declare function registerPassportWebRoutes(router: Router, opts?: Passpor
178
61
  * stateful half on the web group.
179
62
  */
180
63
  export declare function registerPassportApiRoutes(router: Router, opts?: PassportRouteOptions): void;
181
- export {};
182
64
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAiK5D,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;AAE9D,UAAU,MAAM;IACd,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IACpE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IACrE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;CACxE;AAED,yDAAyD;AACzD,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,CAAA;AAEZ,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,eAAe,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;IACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,mBAAmB,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;IAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAA;CAC3D;AAOD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAsS5F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAG/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAG/F"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,oBAAoB,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAQzF,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAEjF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAc5F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAG/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,IAAI,CAG/F"}