@dereekb/firebase-server 14.3.0 → 14.5.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 (43) hide show
  1. package/calcom/package.json +11 -10
  2. package/discord/package.json +14 -10
  3. package/index.esm.js +1295 -317
  4. package/mailgun/package.json +9 -9
  5. package/mcp/index.esm.js +483 -83
  6. package/mcp/package.json +12 -11
  7. package/mcp/src/lib/mcp.config.d.ts +73 -3
  8. package/mcp/src/lib/service/index.d.ts +1 -0
  9. package/mcp/src/lib/service/mcp.server.factory.d.ts +3 -2
  10. package/mcp/src/lib/service/mcp.tool-generator.d.ts +9 -0
  11. package/mcp/src/lib/service/tools/mcp.tool.cli-token.d.ts +62 -0
  12. package/model/package.json +13 -10
  13. package/oidc/index.esm.js +4552 -1902
  14. package/oidc/package.json +12 -10
  15. package/oidc/src/lib/controller/index.d.ts +3 -0
  16. package/oidc/src/lib/controller/oidc.cli-token.config.d.ts +323 -0
  17. package/oidc/src/lib/controller/oidc.cli-token.controller.d.ts +45 -0
  18. package/oidc/src/lib/controller/oidc.cli-token.service.d.ts +138 -0
  19. package/oidc/src/lib/controller/oidc.interaction.controller.d.ts +38 -0
  20. package/oidc/src/lib/index.d.ts +1 -0
  21. package/oidc/src/lib/middleware/oauth-auth.module.d.ts +11 -0
  22. package/oidc/src/lib/oidc.config.d.ts +9 -0
  23. package/oidc/src/lib/oidc.module.d.ts +2 -39
  24. package/oidc/src/lib/oidc.resource-server.d.ts +170 -0
  25. package/oidc/src/lib/service/index.d.ts +2 -0
  26. package/oidc/src/lib/service/oidc.config.service.d.ts +8 -3
  27. package/oidc/src/lib/service/oidc.download-signer.d.ts +17 -0
  28. package/oidc/src/lib/service/oidc.jwt-signing.service.d.ts +112 -0
  29. package/oidc/src/lib/service/oidc.jwt-verify.d.ts +37 -0
  30. package/oidc/src/lib/service/oidc.service.d.ts +35 -4
  31. package/package.json +14 -12
  32. package/src/lib/nest/controller/download/download.api.config.d.ts +203 -0
  33. package/src/lib/nest/controller/download/download.api.controller.d.ts +25 -0
  34. package/src/lib/nest/controller/download/download.api.module.d.ts +47 -0
  35. package/src/lib/nest/controller/download/download.api.service.d.ts +111 -0
  36. package/src/lib/nest/controller/download/index.d.ts +4 -0
  37. package/src/lib/nest/controller/index.d.ts +2 -0
  38. package/src/lib/nest/controller/request.ip.d.ts +60 -0
  39. package/test/index.esm.js +169 -43
  40. package/test/package.json +12 -11
  41. package/test/src/lib/oidc/oidc.test.flow.d.ts +170 -11
  42. package/twilio/package.json +8 -8
  43. package/zoho/package.json +14 -10
@@ -1,9 +1,18 @@
1
1
  import request from 'supertest';
2
2
  import { type INestApplication } from '@nestjs/common';
3
+ import { type Maybe } from '@dereekb/util';
3
4
  import { type OidcProviderProfileKey, type OidcTokenEndpointAuthMethod } from '@dereekb/firebase';
4
5
  import { OidcClientService } from '@dereekb/firebase-server/oidc';
5
6
  /**
6
- * Configuration for {@link performFullOAuthFlow}.
7
+ * A stage of the OAuth authorization code flow that {@link performOAuthFlow} can stop at.
8
+ *
9
+ * - `'auth'` — stop on the `/oidc/auth` response, before the login interaction.
10
+ * - `'callback'` — stop on the client callback redirect, before the token exchange.
11
+ * - `'token'` — run the whole flow, through the token exchange.
12
+ */
13
+ export type OAuthTestFlowStage = 'auth' | 'callback' | 'token';
14
+ /**
15
+ * Configuration for {@link performOAuthFlow} / {@link performFullOAuthFlow}.
7
16
  */
8
17
  export interface OAuthTestFlowConfig {
9
18
  /**
@@ -53,6 +62,36 @@ export interface OAuthTestFlowConfig {
53
62
  * to consent (or straight to the callback when nothing new needs consenting and `prompt` is unset).
54
63
  */
55
64
  readonly session?: OAuthTestFlowSession;
65
+ /**
66
+ * RFC 8707 `resource` indicator, sent on both `/oidc/auth` and `/oidc/token`.
67
+ *
68
+ * Must match a key registered on the provider's `resourceServers` config. The issued access
69
+ * token then carries that entry's `audience` and — when the entry sets
70
+ * `accessTokenFormat: 'jwt'` — is an RS256 JWT a remote resource server can verify against the
71
+ * provider's JWKS, rather than the default opaque token only the provider itself can validate.
72
+ */
73
+ readonly resource?: string;
74
+ /**
75
+ * Extra query parameters merged onto the `/oidc/auth` request, for parameters this config does
76
+ * not model explicitly.
77
+ */
78
+ readonly extraAuthParams?: Record<string, string | number>;
79
+ /**
80
+ * The stage to stop the flow at. Defaults to `'token'`, the full flow.
81
+ *
82
+ * - `'auth'` — issue the `/oidc/auth` request and stop, exposing the raw redirect response on
83
+ * {@link OAuthTestFlowResult.authResponse}. Nothing logs in, so no `uid` is needed.
84
+ * - `'callback'` — drive auth → login → consent → the callback redirect and stop before the token
85
+ * exchange, exposing {@link OAuthTestFlowResult.callbackUrl} and
86
+ * {@link OAuthTestFlowResult.consentRedirectUrl}. A callback carrying an `error` instead of a
87
+ * `code` (e.g. `access_denied`) is not treated as a failure at this stage, so a caller can assert
88
+ * on it.
89
+ * - `'token'` — the full flow, exchanging the authorization code for tokens.
90
+ *
91
+ * Ignored by {@link performFullOAuthFlow} / {@link setupAndPerformFullOAuthFlow}, whose result type
92
+ * guarantees tokens; stop early with {@link performOAuthFlow} / {@link setupAndPerformOAuthFlow}.
93
+ */
94
+ readonly stopAtStage?: OAuthTestFlowStage;
56
95
  }
57
96
  /**
58
97
  * The client and cookies a flow ran with, for chaining a second flow onto the same provider session.
@@ -76,44 +115,164 @@ export interface OAuthTestFlowCookieJar {
76
115
  readonly collectCookies: (res: request.Response) => void;
77
116
  readonly cookieHeader: () => string;
78
117
  }
79
- export interface PerformFullOAuthFlowResult {
80
- readonly accessToken: string;
81
- readonly idToken: string;
118
+ /**
119
+ * Result of {@link performOAuthFlow}, covering every {@link OAuthTestFlowStage} it can stop at.
120
+ *
121
+ * Every field a stage produced is populated; the fields belonging to later stages are undefined.
122
+ */
123
+ export interface OAuthTestFlowResult {
82
124
  /**
83
- * The space-separated scope the token endpoint reported for the access token.
125
+ * The stage the flow stopped at.
84
126
  */
85
- readonly scope: string;
127
+ readonly stage: OAuthTestFlowStage;
128
+ /**
129
+ * The raw `/oidc/auth` response, before any redirect was followed.
130
+ *
131
+ * Always populated. This is what a flow stopped at the `'auth'` stage asserts on — it may be a
132
+ * redirect to the login interaction, or an error callback (e.g. `error=invalid_target`).
133
+ */
134
+ readonly authResponse: request.Response;
135
+ /**
136
+ * The PKCE `code_verifier` the flow's `code_challenge` was derived from.
137
+ *
138
+ * Always populated, for a caller that performs its own `/oidc/token` request after stopping at the
139
+ * `'callback'` stage.
140
+ */
141
+ readonly codeVerifier: string;
142
+ /**
143
+ * The URL of the consent SCREEN the provider redirected to, when the flow reached it.
144
+ *
145
+ * Its `scopes` query parameter is the checkbox list the consent UI renders, so it is what scope
146
+ * withholding (e.g. an admin-only scope kept off a non-admin's screen) acts on.
147
+ *
148
+ * Undefined when the flow stopped at the `'auth'` stage, or when nothing needed consenting.
149
+ */
150
+ readonly consentRedirectUrl?: Maybe<URL>;
151
+ /**
152
+ * The client callback URL the flow ended on, carrying either a `code` or an `error`.
153
+ *
154
+ * Undefined when the flow stopped at the `'auth'` stage.
155
+ */
156
+ readonly callbackUrl?: Maybe<URL>;
157
+ /**
158
+ * The access token the token endpoint issued. Undefined unless the flow ran to the `'token'` stage.
159
+ */
160
+ readonly accessToken?: string;
161
+ /**
162
+ * The ID token the token endpoint issued. Undefined unless the flow ran to the `'token'` stage.
163
+ */
164
+ readonly idToken?: string;
165
+ /**
166
+ * The refresh token the token endpoint issued.
167
+ *
168
+ * Only present when the flow requested `offline_access` — the provider issues a refresh token for
169
+ * no other reason. Undefined unless the flow ran to the `'token'` stage.
170
+ *
171
+ * This is what a revocation test spends: a refresh exchange is the one operation that keeps working
172
+ * against a still-live Grant and fails with `invalid_grant` the instant the Grant is destroyed.
173
+ */
174
+ readonly refreshToken?: string;
175
+ /**
176
+ * The `token_type` the token endpoint reported for the access token.
177
+ */
178
+ readonly tokenType?: string;
179
+ /**
180
+ * The space-separated scope the token endpoint reported for the access token. Undefined unless the
181
+ * flow ran to the `'token'` stage.
182
+ */
183
+ readonly scope?: string;
86
184
  /**
87
185
  * The client and cookies this flow ran with, for chaining another flow onto the same session via
88
- * {@link OAuthTestFlowConfig.session}.
186
+ * {@link OAuthTestFlowConfig.session} — and for the cookie header a caller's own `/oidc/token`
187
+ * request needs, via `session.cookieJar.cookieHeader()`.
89
188
  */
90
189
  readonly session: OAuthTestFlowSession;
91
190
  }
92
191
  /**
93
- * Input for {@link performFullOAuthFlow}.
192
+ * Result of {@link performFullOAuthFlow} — an {@link OAuthTestFlowResult} that ran to the `'token'`
193
+ * stage, so the callback and the tokens are guaranteed.
94
194
  */
95
- export interface PerformFullOAuthFlowInput {
195
+ export interface PerformFullOAuthFlowResult extends OAuthTestFlowResult {
196
+ readonly callbackUrl: URL;
197
+ readonly accessToken: string;
198
+ readonly idToken: string;
199
+ readonly scope: string;
200
+ }
201
+ /**
202
+ * Input for {@link performOAuthFlow}.
203
+ */
204
+ export interface PerformOAuthFlowInput {
96
205
  readonly server: ReturnType<INestApplication['getHttpServer']>;
97
206
  readonly oidcClientService: OidcClientService;
98
207
  readonly nestApp: INestApplication;
99
- readonly uid: string;
208
+ /**
209
+ * Firebase user ID for whom the test ID token is minted and the flow is authorized.
210
+ *
211
+ * Only optional for a flow that stops at the `'auth'` stage, which never reaches the login
212
+ * interaction. Any later stage throws when it is missing.
213
+ */
214
+ readonly uid?: Maybe<string>;
100
215
  readonly config?: OAuthTestFlowConfig;
101
216
  }
217
+ /**
218
+ * Input for {@link performFullOAuthFlow}.
219
+ */
220
+ export interface PerformFullOAuthFlowInput extends PerformOAuthFlowInput {
221
+ readonly uid: string;
222
+ }
223
+ /**
224
+ * Performs the OAuth authorization code flow with PKCE, up to the configured
225
+ * {@link OAuthTestFlowConfig.stopAtStage}.
226
+ *
227
+ * Steps: create client → PKCE → auth redirect → login → consent → code exchange → token
228
+ *
229
+ * Stopping early is how a test asserts on an intermediate the completed flow discards — the raw
230
+ * `/oidc/auth` response, the consent screen's offered `scopes`, or a callback that came back carrying
231
+ * an `error` instead of a `code`. A stage before `'token'` never exchanges the code, so it never
232
+ * throws on such a callback; the caller asserts on {@link OAuthTestFlowResult.callbackUrl} instead,
233
+ * and can run its own `/oidc/token` request with {@link OAuthTestFlowResult.codeVerifier} and the
234
+ * session's cookie header.
235
+ *
236
+ * @param input - Bag of services and overrides needed to drive the flow.
237
+ * @param input.server - HTTP server returned by `nestApp.getHttpServer()` against which all supertest requests are issued.
238
+ * @param input.oidcClientService - Service used to create the OAuth client whose credentials drive the flow.
239
+ * @param input.nestApp - Initialized NestJS application; used to resolve {@link OidcAccountService} for project-id-derived ID tokens and default scopes.
240
+ * @param input.uid - Firebase user ID for whom the test ID token is minted; required for any stage past `'auth'`.
241
+ * @param input.config - Optional flow overrides (scopes, redirect URI, client name, token endpoint auth method, provider profiles, stop stage).
242
+ * @returns The intermediates the flow produced, plus the tokens when it ran to the `'token'` stage.
243
+ * @throws {Error} When a stage past `'auth'` is requested without a `uid`, or when the token exchange step fails (the response body and status are included in the message).
244
+ */
245
+ export declare function performOAuthFlow(input: PerformOAuthFlowInput): Promise<OAuthTestFlowResult>;
102
246
  /**
103
247
  * Performs the full OAuth authorization code flow with PKCE and returns tokens.
104
248
  *
105
249
  * Steps: create client → PKCE → auth redirect → login → consent → code exchange → token
106
250
  *
251
+ * Always runs to the `'token'` stage — {@link OAuthTestFlowConfig.stopAtStage} is ignored here, since
252
+ * this function's result guarantees tokens. Use {@link performOAuthFlow} to stop earlier.
253
+ *
107
254
  * @param input - Bag of services and overrides needed to drive the flow end-to-end.
108
255
  * @param input.server - HTTP server returned by `nestApp.getHttpServer()` against which all supertest requests are issued.
109
256
  * @param input.oidcClientService - Service used to create the OAuth client whose credentials drive the flow.
110
257
  * @param input.nestApp - Initialized NestJS application; used to resolve {@link OidcAccountService} for project-id-derived ID tokens and default scopes.
111
258
  * @param input.uid - Firebase user ID for whom the test ID token is minted and the OAuth flow is authorized.
112
259
  * @param input.config - Optional flow overrides (scopes, redirect URI, client name, token endpoint auth method, provider profiles).
113
- * @returns The exchanged access token and ID token from the OIDC `/token` endpoint.
260
+ * @returns The exchanged access token and ID token from the OIDC `/token` endpoint, plus the flow's intermediates.
114
261
  * @throws {Error} When the token exchange step fails (the response body and status are included in the message).
115
262
  */
116
263
  export declare function performFullOAuthFlow(input: PerformFullOAuthFlowInput): Promise<PerformFullOAuthFlowResult>;
264
+ /**
265
+ * Higher-level helper that resolves OIDC services from the NestJS DI container,
266
+ * rotates JWKS keys, and then performs the OAuth flow up to {@link OAuthTestFlowConfig.stopAtStage}.
267
+ *
268
+ * This avoids callers needing to import from `@dereekb/firebase-server/oidc` directly.
269
+ *
270
+ * @param nestApp - Initialized NestJS application from which {@link JwksService} and {@link OidcClientService} are resolved.
271
+ * @param uid - Firebase user ID for whom the OAuth flow is authorized; only omittable for the `'auth'` stage.
272
+ * @param config - Optional flow overrides (scopes, redirect URI, client name, token endpoint auth method, provider profiles, stop stage).
273
+ * @returns The result of {@link performOAuthFlow}.
274
+ */
275
+ export declare function setupAndPerformOAuthFlow(nestApp: INestApplication, uid: Maybe<string>, config?: OAuthTestFlowConfig): Promise<OAuthTestFlowResult>;
117
276
  /**
118
277
  * Higher-level helper that resolves OIDC services from the NestJS DI container,
119
278
  * rotates JWKS keys, and then performs the full OAuth flow.
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/twilio",
3
- "version": "14.3.0",
3
+ "version": "14.5.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/date": "14.3.0",
8
- "@dereekb/firebase": "14.3.0",
9
- "@dereekb/firebase-server": "14.3.0",
10
- "@dereekb/model": "14.3.0",
11
- "@dereekb/nestjs": "14.3.0",
12
- "@dereekb/rxjs": "14.3.0",
13
- "@dereekb/util": "14.3.0"
7
+ "@dereekb/date": "14.5.0",
8
+ "@dereekb/firebase": "14.5.0",
9
+ "@dereekb/firebase-server": "14.5.0",
10
+ "@dereekb/model": "14.5.0",
11
+ "@dereekb/nestjs": "14.5.0",
12
+ "@dereekb/rxjs": "14.5.0",
13
+ "@dereekb/util": "14.5.0"
14
14
  },
15
15
  "exports": {
16
16
  "./package.json": "./package.json",
package/zoho/package.json CHANGED
@@ -1,22 +1,26 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/zoho",
3
- "version": "14.3.0",
3
+ "version": "14.5.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/analytics": "14.3.0",
8
- "@dereekb/date": "14.3.0",
9
- "@dereekb/model": "14.3.0",
10
- "@dereekb/nestjs": "14.3.0",
11
- "@dereekb/rxjs": "14.3.0",
12
- "@dereekb/firebase": "14.3.0",
13
- "@dereekb/firebase-server": "14.3.0",
14
- "@dereekb/util": "14.3.0",
15
- "@dereekb/zoho": "14.3.0",
7
+ "@dereekb/analytics": "14.5.0",
8
+ "@dereekb/date": "14.5.0",
9
+ "@dereekb/firebase": "14.5.0",
10
+ "@dereekb/firebase-server": "14.5.0",
11
+ "@dereekb/model": "14.5.0",
12
+ "@dereekb/nestjs": "14.5.0",
13
+ "@dereekb/rxjs": "14.5.0",
14
+ "@dereekb/util": "14.5.0",
15
+ "@dereekb/zoho": "14.5.0",
16
16
  "@nestjs/common": "^12.0.1",
17
17
  "@nestjs/config": "^12.0.0",
18
18
  "express": "^5.2.1"
19
19
  },
20
+ "devDependencies": {
21
+ "@nestjs/testing": "^12.0.1",
22
+ "date-fns": "^4.1.0"
23
+ },
20
24
  "exports": {
21
25
  "./package.json": "./package.json",
22
26
  ".": {