@dereekb/firebase-server 14.3.0 → 14.4.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.
package/oidc/package.json CHANGED
@@ -1,22 +1,24 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/oidc",
3
- "version": "14.3.0",
3
+ "version": "14.4.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/firebase": "14.3.0",
10
- "@dereekb/firebase-server": "14.3.0",
11
- "@dereekb/model": "14.3.0",
12
- "@dereekb/nestjs": "14.3.0",
13
- "@dereekb/rxjs": "14.3.0",
14
- "@dereekb/util": "14.3.0",
15
- "@dereekb/zoho": "14.3.0",
7
+ "@dereekb/analytics": "14.4.0",
8
+ "@dereekb/date": "14.4.0",
9
+ "@dereekb/firebase": "14.4.0",
10
+ "@dereekb/firebase-server": "14.4.0",
11
+ "@dereekb/model": "14.4.0",
12
+ "@dereekb/nestjs": "14.4.0",
13
+ "@dereekb/oauth-resource": "14.4.0",
14
+ "@dereekb/rxjs": "14.4.0",
15
+ "@dereekb/util": "14.4.0",
16
+ "@dereekb/zoho": "14.4.0",
16
17
  "@nestjs/common": "^12.0.1",
17
18
  "@nestjs/config": "^12.0.0",
18
19
  "express": "^5.2.1",
19
20
  "firebase-admin": "^13.10.0",
21
+ "jose": "^6.2.12",
20
22
  "nanoid": "^6.0.1",
21
23
  "oidc-provider": "^9.8.2"
22
24
  },
@@ -3,5 +3,6 @@ export * from './model';
3
3
  export * from './oidc.config';
4
4
  export * from './controller';
5
5
  export * from './oidc.module';
6
+ export * from './oidc.resource-server';
6
7
  export * from './profile';
7
8
  export * from './service';
@@ -52,6 +52,9 @@ export declare abstract class OidcAuthMiddlewareConfig {
52
52
  * included as the RFC 9728 `resource_metadata` hint so clients can locate the
53
53
  * discovery doc directly instead of relying on origin-rooted path-walkback.
54
54
  *
55
+ * Delegates to `@dereekb/oauth-resource`'s builder so the challenge an off-box resource server
56
+ * emits and the one this API emits are produced by the same code.
57
+ *
55
58
  * @param error - The RFC 6750 `error` token (e.g. `invalid_token`, `invalid_request`).
56
59
  * @param resourceMetadataUrl - Optional protected-resource metadata URL.
57
60
  * @returns Header value, e.g. `Bearer resource_metadata="…", error="invalid_token"`.
@@ -1,6 +1,6 @@
1
1
  import { type ModuleMetadata } from '@nestjs/common';
2
2
  import { ConfigService } from '@nestjs/config';
3
- import { OidcModuleConfig, type OidcProviderConfig, type OidcResourceServerInfo } from './oidc.config';
3
+ import { OidcModuleConfig } from './oidc.config';
4
4
  import { type FirestoreContext } from '@dereekb/firebase';
5
5
  import { FirebaseServerEnvService } from '@dereekb/firebase-server';
6
6
  import { OidcServerFirestoreCollections } from './model/model';
@@ -88,43 +88,6 @@ export declare function oidcModuleConfigFactory(configService: ConfigService, en
88
88
  * @returns The discovery URL, or `undefined` if `appMcpUrl` is not set.
89
89
  */
90
90
  export declare function deriveResourceMetadataUrlFromEnv(envService: FirebaseServerEnvService): string | undefined;
91
- /**
92
- * Input for {@link buildFirebaseServerMcpResourceServer}.
93
- */
94
- export interface BuildFirebaseServerMcpResourceServerInput {
95
- /**
96
- * The Firebase server environment service. The MCP URL is read from `envService.appMcpUrl`.
97
- */
98
- readonly envService: FirebaseServerEnvService;
99
- /**
100
- * The OIDC provider config whose scopes back the resource server's `scope` value.
101
- */
102
- readonly providerConfig: OidcProviderConfig;
103
- }
104
- /**
105
- * Builds a single-entry {@link OidcResourceServerInfo} map for the MCP endpoint
106
- * declared on `envService.appMcpUrl`, with `scope` set to every scope declared
107
- * on `providerConfig.claims` (so any scope the provider issues is valid on the
108
- * resource server) and `audience` set to the MCP URL.
109
- *
110
- * Returns `undefined` when no `appMcpUrl` is configured.
111
- *
112
- * Used internally by {@link oidcModuleMetadata} when {@link OidcModuleConfig.configureMcpResourceServer}
113
- * is enabled, and exported for apps that need to combine the MCP resource server
114
- * with additional app-specific entries:
115
- *
116
- * @example
117
- * ```ts
118
- * resourceServers: {
119
- * ...(buildFirebaseServerMcpResourceServer({ envService, providerConfig: APP_PROVIDER_CONFIG }) ?? {}),
120
- * 'https://api.example.com/extras': {
121
- * scope: 'openid profile',
122
- * audience: 'https://api.example.com/extras'
123
- * }
124
- * }
125
- * ```
126
- */
127
- export declare function buildFirebaseServerMcpResourceServer(input: BuildFirebaseServerMcpResourceServerInput): Record<string, OidcResourceServerInfo> | undefined;
128
91
  /**
129
92
  * Factory that creates {@link OidcServerFirestoreCollections} using the provided Firestore context
130
93
  * and JWKS encryption config from {@link OidcModuleConfig}.
@@ -0,0 +1,170 @@
1
+ import { type BuildIssuerProfilesConfig, type BuildIssuerProfilesOidcIssuerInput } from '@dereekb/oauth-resource';
2
+ import { type FirebaseServerEnvService } from '@dereekb/firebase-server';
3
+ import { type Maybe, type Seconds, type WebsiteUrlWithPrefix } from '@dereekb/util';
4
+ import { type OidcModuleConfig, type OidcProviderConfig, type OidcResourceServerInfo } from './oidc.config';
5
+ export interface BuildOidcResourceServerConfig {
6
+ /**
7
+ * The RFC 8707 resource indicator — the value a client sends as `resource=` on `/authorize` and
8
+ * `/token`, and the key this entry is registered under. Usually the resource's full URL, e.g.
9
+ * `https://db.example.com/mcp`.
10
+ */
11
+ readonly url: WebsiteUrlWithPrefix;
12
+ /**
13
+ * Space-delimited scopes valid on this resource server. Issued access tokens are filtered to the
14
+ * intersection of the client-requested scopes and this allow-list, so keep it to what the
15
+ * resource actually understands rather than every scope the provider issues.
16
+ */
17
+ readonly scope: string;
18
+ /**
19
+ * `aud` claim placed on tokens bound to this resource. Defaults to {@link url}.
20
+ *
21
+ * An OFF-BOX resource server usually wants its ORIGIN here (`https://db.example.com`) rather
22
+ * than the `/mcp` resource-indicator URL, so one audience covers every route it serves.
23
+ */
24
+ readonly audience?: Maybe<string>;
25
+ /**
26
+ * Access-token format. Defaults to oidc-provider's `'opaque'`.
27
+ *
28
+ * **Set `'jwt'` for any resource server that is not this API process.** An opaque access token is
29
+ * a database key: it can only be validated by the issuer's own adapter store, so a remote service
30
+ * fundamentally cannot verify it. A `'jwt'` token is an RS256 JWT signed with the provider's
31
+ * active JWKS key (no extra provider config needed — `getResourceServerConfig` falls back to
32
+ * `clientDefaults.id_token_signed_response_alg`, i.e. `RS256`), which any service can verify via
33
+ * `@dereekb/oauth-resource` against the published `/.well-known/jwks.json`.
34
+ *
35
+ * The trade-off: a JWT access token is NOT persisted by oidc-provider, so it has no adapter
36
+ * record and **cannot be revoked before `exp`**. Revoking the Grant stops refresh and future
37
+ * issuance but leaves outstanding JWTs valid — keep {@link accessTokenTTL} short.
38
+ */
39
+ readonly accessTokenFormat?: Maybe<'opaque' | 'jwt'>;
40
+ /**
41
+ * Access-token TTL for this resource, in seconds. Falls back to the provider's `ttl.AccessToken`.
42
+ */
43
+ readonly accessTokenTTL?: Maybe<Seconds>;
44
+ }
45
+ /**
46
+ * Builds a single-entry {@link OidcResourceServerInfo} map for an RFC 8707 resource indicator.
47
+ *
48
+ * This is the supported way to declare a resource server the provider issues tokens for —
49
+ * including one that runs OFF-BOX (a Docker'd sidecar, a worker, a standalone MCP host), which is
50
+ * what {@link BuildOidcResourceServerConfig.accessTokenFormat} `'jwt'` exists for.
51
+ *
52
+ * @param config - The resource indicator, its scopes, and the token shape to issue for it.
53
+ * @returns A single-entry map keyed by the resource indicator.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const DB_ORIGIN = 'https://db.example.com';
58
+ *
59
+ * oidcModuleMetadata({
60
+ * dependencyModule: MyOidcDependencyModule,
61
+ * config: {
62
+ * resourceServers: buildOidcResourceServer({
63
+ * url: `${DB_ORIGIN}/mcp`,
64
+ * scope: 'openid profile email offline_access',
65
+ * audience: DB_ORIGIN,
66
+ * accessTokenFormat: 'jwt',
67
+ * accessTokenTTL: 3600
68
+ * })
69
+ * }
70
+ * })
71
+ * ```
72
+ */
73
+ export declare function buildOidcResourceServer(config: BuildOidcResourceServerConfig): Record<string, OidcResourceServerInfo>;
74
+ /**
75
+ * Input for {@link buildFirebaseServerMcpResourceServer}.
76
+ */
77
+ export interface BuildFirebaseServerMcpResourceServerInput {
78
+ /**
79
+ * The Firebase server environment service. The MCP URL is read from `envService.appMcpUrl`.
80
+ */
81
+ readonly envService: FirebaseServerEnvService;
82
+ /**
83
+ * The OIDC provider config whose scopes back the resource server's `scope` value.
84
+ */
85
+ readonly providerConfig: OidcProviderConfig;
86
+ /**
87
+ * Access-token format. Defaults to oidc-provider's `'opaque'`.
88
+ *
89
+ * See {@link BuildOidcResourceServerConfig.accessTokenFormat}.
90
+ */
91
+ readonly accessTokenFormat?: Maybe<'opaque' | 'jwt'>;
92
+ /**
93
+ * Access-token TTL for the MCP resource, in seconds.
94
+ */
95
+ readonly accessTokenTTL?: Maybe<Seconds>;
96
+ }
97
+ /**
98
+ * Builds a single-entry {@link OidcResourceServerInfo} map for the MCP endpoint
99
+ * declared on `envService.appMcpUrl`, with `scope` set to every scope declared
100
+ * on `providerConfig.claims` (so any scope the provider issues is valid on the
101
+ * resource server) and `audience` set to the MCP URL.
102
+ *
103
+ * Returns `undefined` when no `appMcpUrl` is configured.
104
+ *
105
+ * Used internally by `oidcModuleMetadata` when `OidcModuleConfig.configureMcpResourceServer`
106
+ * is enabled.
107
+ *
108
+ * @param input - The environment service and provider config backing the entry.
109
+ * @returns The single-entry map, or `undefined` when no MCP URL is configured.
110
+ *
111
+ * @deprecated Prefer {@link buildOidcResourceServer}, which takes the URL, scope, audience, and
112
+ * token format explicitly instead of deriving a fixed shape from the environment.
113
+ */
114
+ export declare function buildFirebaseServerMcpResourceServer(input: BuildFirebaseServerMcpResourceServerInput): Record<string, OidcResourceServerInfo> | undefined;
115
+ export interface FirebaseServerIssuerProfilesConfig {
116
+ /**
117
+ * The provider's own module config. Its `issuer` becomes the trusted OIDC issuer, and every
118
+ * registered `resourceServers` entry contributes its key and `audience` to the accepted
119
+ * audience list.
120
+ */
121
+ readonly oidcModuleConfig: Pick<OidcModuleConfig, 'issuer' | 'resourceServers'>;
122
+ /**
123
+ * Firebase project ids whose ID tokens the resource server also trusts.
124
+ */
125
+ readonly firebaseProjectIds?: Maybe<readonly string[]>;
126
+ /**
127
+ * Extra audiences to accept beyond the ones derived from `resourceServers` — typically the
128
+ * resource server's own origin when it is not itself a registered resource indicator.
129
+ */
130
+ readonly audiences?: Maybe<readonly string[]>;
131
+ /**
132
+ * Overrides how the provider's verification keys are resolved, bypassing discovery. The API
133
+ * verifying its OWN tokens in-process passes a local key set here rather than making an HTTP
134
+ * call back to itself.
135
+ */
136
+ readonly getKey?: Maybe<Required<Exclude<BuildIssuerProfilesOidcIssuerInput, string>>['getKey']>;
137
+ /**
138
+ * `fetch` used for OIDC discovery; injected in specs.
139
+ */
140
+ readonly fetch?: Maybe<typeof fetch>;
141
+ }
142
+ /**
143
+ * Emits the `@dereekb/oauth-resource` {@link BuildIssuerProfilesConfig} for THIS provider, so an
144
+ * API and the satellite services it issues tokens for cannot drift on issuer / audience strings —
145
+ * both sides read the same `OidcModuleConfig`.
146
+ *
147
+ * The type dependency points `firebase-server → oauth-resource` and never the reverse: the light
148
+ * verify package must stay installable in a plain Express service with no Firebase, Nest, or
149
+ * oidc-provider in its install graph.
150
+ *
151
+ * @param config - The provider's module config plus any extra trusted projects / audiences.
152
+ * @returns The issuer-profile config to hand to `buildIssuerProfiles()`.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * // inside the API, to hand its satellites a config they cannot get wrong
157
+ * const profilesConfig = firebaseServerIssuerProfiles({ oidcModuleConfig, firebaseProjectIds: [projectId] });
158
+ * const profiles = buildIssuerProfiles(profilesConfig);
159
+ * ```
160
+ */
161
+ export declare function firebaseServerIssuerProfiles(config: FirebaseServerIssuerProfilesConfig): BuildIssuerProfilesConfig;
162
+ /**
163
+ * Reads every audience a registered resource-server map can put on an access token: each entry's
164
+ * key (the resource indicator, which oidc-provider uses as the audience by default) plus its
165
+ * explicit `audience` when one is configured.
166
+ *
167
+ * @param resourceServers - The provider's registered resource servers, if any.
168
+ * @returns The unique audience values.
169
+ */
170
+ export declare function oidcResourceServerAudiences(resourceServers: Maybe<Record<string, OidcResourceServerInfo>>): string[];
@@ -11,3 +11,4 @@ export * from './oidc.client.service';
11
11
  export * from './oidc.interaction.service';
12
12
  export * from './oidc.grant';
13
13
  export * from './oidc.interaction-policy';
14
+ export * from './oidc.jwt-signing.service';
@@ -0,0 +1,77 @@
1
+ import { type Maybe, type Milliseconds, type Seconds } from '@dereekb/util';
2
+ import { OidcModuleConfig } from '../oidc.config';
3
+ import { JwksService } from './oidc.jwks.service';
4
+ /**
5
+ * Default lifetime of a minted JWT, in seconds.
6
+ */
7
+ export declare const DEFAULT_OIDC_SIGNED_JWT_EXPIRES_IN_SECONDS: Seconds;
8
+ /**
9
+ * How long the active signing key is cached before it is re-read from the JWKS store.
10
+ *
11
+ * A rotation is picked up within this window; rotated keys stay in the public JWKS for 30 days, so
12
+ * tokens signed with the previous key keep verifying in the meantime.
13
+ */
14
+ export declare const DEFAULT_OIDC_JWT_SIGNING_KEY_CACHE_MS: Milliseconds;
15
+ /**
16
+ * Header `typ` for a minted JWT: an RFC 9068 JWT access token, matching the format oidc-provider
17
+ * uses for the `accessTokenFormat: 'jwt'` resource-server tokens.
18
+ */
19
+ export declare const DEFAULT_OIDC_SIGNED_JWT_TYP = "at+jwt";
20
+ export interface OidcSignJwtInput {
21
+ /**
22
+ * `aud` claim(s) — the resource the token is for, e.g. an off-box service's origin.
23
+ */
24
+ readonly audience: string | readonly string[];
25
+ /**
26
+ * `sub` claim — the first-party identity of the caller, e.g. `demo-api`.
27
+ */
28
+ readonly subject: string;
29
+ /**
30
+ * Lifetime in seconds. Defaults to {@link DEFAULT_OIDC_SIGNED_JWT_EXPIRES_IN_SECONDS}.
31
+ */
32
+ readonly expiresIn?: Maybe<Seconds>;
33
+ /**
34
+ * Extra claims merged onto the payload, e.g. `{ client_id, scope }`.
35
+ */
36
+ readonly claims?: Maybe<Record<string, unknown>>;
37
+ /**
38
+ * Header `typ`. Defaults to {@link DEFAULT_OIDC_SIGNED_JWT_TYP}.
39
+ */
40
+ readonly typ?: Maybe<string>;
41
+ }
42
+ export interface OidcSignedJwt {
43
+ readonly token: string;
44
+ readonly expiresAt: Date;
45
+ /**
46
+ * `kid` of the JWKS key that signed the token.
47
+ */
48
+ readonly kid: string;
49
+ }
50
+ /**
51
+ * Signs first-party JWTs with the OIDC provider's active JWKS signing key.
52
+ *
53
+ * The result is an RS256 token with `iss` = this provider's issuer, so any resource server that
54
+ * already trusts the provider's JWKS for OAuth access tokens verifies it with no new secret or
55
+ * trust anchor: "the API mints a token for the satellite service" is literally "sign with the
56
+ * active key, `aud` = the satellite's origin". The counterpart on the resource server is
57
+ * `verifyBearerJwt` from `@dereekb/oauth-resource`, whose `oidc` issuer profile discovers this
58
+ * provider's `jwks_uri` from its own discovery document.
59
+ *
60
+ * Registered and exported by `oidcModuleMetadata`, so a downstream app injects it with no extra
61
+ * wiring. Pair it with `createCachedTokenProvider` from `@dereekb/util/oidc` to hold a minted
62
+ * token until it nears expiry instead of re-signing per call.
63
+ */
64
+ export declare class OidcJwtSigningService {
65
+ private readonly _jwks;
66
+ private readonly _config;
67
+ private _cached;
68
+ constructor(_jwks: JwksService, _config: OidcModuleConfig);
69
+ /**
70
+ * Mints a signed JWT.
71
+ *
72
+ * @param input - Audience, subject, lifetime, and extra claims.
73
+ * @returns The compact token, its expiry, and the signing key id.
74
+ */
75
+ signJwt(input: OidcSignJwtInput): Promise<OidcSignedJwt>;
76
+ private _loadSigningKey;
77
+ }
@@ -0,0 +1,37 @@
1
+ import { type IssuerProfiles } from '@dereekb/oauth-resource';
2
+ import { type JWTVerifyGetKey } from 'jose';
3
+ import { type OidcModuleConfig } from '../oidc.config';
4
+ import { type JwksService } from './oidc.jwks.service';
5
+ /**
6
+ * Builds a jose {@link JWTVerifyGetKey} backed by the provider's OWN published JWKS, read directly
7
+ * from {@link JwksService} rather than over HTTP.
8
+ *
9
+ * An in-process verifier must not `createRemoteJWKSet` against its own `/.well-known/jwks.json`:
10
+ * that would make every bearer-authenticated request depend on the process being able to reach
11
+ * itself over the network (which it may not be, behind a load balancer, in a Functions emulator,
12
+ * or under supertest).
13
+ *
14
+ * The key set is cached and re-read only when a token presents a `kid` the cache does not hold —
15
+ * so a freshly rotated key is picked up on its first use instead of after a fixed TTL.
16
+ *
17
+ * @param jwksService - The provider's JWKS service.
18
+ * @returns The key resolver.
19
+ */
20
+ export declare function jwksServiceVerifyGetKey(jwksService: JwksService): JWTVerifyGetKey;
21
+ /**
22
+ * Builds the {@link IssuerProfiles} the provider uses to verify its OWN JWT-format access tokens
23
+ * in-process.
24
+ *
25
+ * A JWT access token is issued for a specific `resource=`, so it carries THAT resource server's
26
+ * audience — not the API's own identity. The accepted audiences are therefore every registered
27
+ * `resourceServers` key and audience, plus the issuer itself. The trust decision that implies is
28
+ * deliberate and narrow: a resource server the user consented to may present the token it was
29
+ * given back to the API that issued it. Scope enforcement is unchanged and still does the real
30
+ * authorization work (e.g. the admin-only `session.firestore` consent gate and the endpoint's own
31
+ * admin predicate).
32
+ *
33
+ * @param config - The provider's module config.
34
+ * @param jwksService - The provider's JWKS service, used for local key resolution.
35
+ * @returns The issuer profiles, holding exactly this provider.
36
+ */
37
+ export declare function oidcProviderIssuerProfiles(config: OidcModuleConfig, jwksService: JwksService): IssuerProfiles;
@@ -23,6 +23,11 @@ export interface ResolveLoginDurationTier {
23
23
  */
24
24
  readonly hasServiceScope: boolean;
25
25
  }
26
+ /**
27
+ * Claims a JWT access token carries that the {@link OidcAuthData} shape sets explicitly, and that
28
+ * are therefore NOT app account claims.
29
+ */
30
+ export declare const OIDC_JWT_ACCESS_TOKEN_RESERVED_CLAIMS: readonly string[];
26
31
  /**
27
32
  * Core OIDC service that wraps the oidc-provider instance and exposes
28
33
  * typed methods for interaction handling, provider initialization, and JWKS management.
@@ -36,6 +41,7 @@ export declare class OidcService {
36
41
  private readonly encryptionService;
37
42
  private readonly _logger;
38
43
  private readonly _getProvider;
44
+ private readonly _getIssuerProfiles;
39
45
  constructor(config: OidcModuleConfig, providerConfigService: OidcProviderConfigService, jwksService: JwksService, accountService: OidcAccountService, collections: OidcServerFirestoreCollections, encryptionService: OidcEncryptionService);
40
46
  /**
41
47
  * Returns the oidc-provider instance, initializing it on first access.
@@ -67,15 +73,40 @@ export declare class OidcService {
67
73
  dbx_max_session_ttl?: number;
68
74
  } | undefined, tier: ResolveLoginDurationTier): number;
69
75
  /**
70
- * Verifies an opaque access token and returns the {@link OidcAuthData}.
76
+ * Verifies an access token and returns the {@link OidcAuthData}.
77
+ *
78
+ * Two formats are accepted, because oidc-provider issues two:
79
+ *
80
+ * - **opaque** (the default) — a database key. Looked up through the provider's `AccessToken`
81
+ * model, which reads the Firestore adapter record written at issuance.
82
+ * - **JWT** (a resource server registered with `accessTokenFormat: 'jwt'`) — verified by
83
+ * signature against this provider's own JWKS via `@dereekb/oauth-resource`. A JWT access token
84
+ * is deliberately NOT persisted by oidc-provider (`lib/models/formats/jwt.js` returns no
85
+ * payload, so `base_model.js` skips the `adapter.upsert`), which means `AccessToken.find()`
86
+ * always misses for one and the store lookup alone would 401 every token the provider just
87
+ * issued.
71
88
  *
72
- * Uses the provider's `AccessToken` model to look up the token and extract
73
- * the account ID, scope, and client ID.
89
+ * The same absence of an adapter record is why a JWT access token **cannot be revoked before
90
+ * `exp`**: {@link revokeGrant} deletes the Grant and every persisted token referencing it, which
91
+ * stops refresh and future issuance, but an outstanding JWT stays verifiable until it expires.
92
+ * Keep `accessTokenTTL` short on any resource server that opts into the JWT format.
74
93
  *
75
- * @param rawToken - The opaque access token string.
94
+ * @param rawToken - The access token string, opaque or JWT.
76
95
  * @returns The auth context, or `undefined` if the token is invalid or expired.
77
96
  */
78
97
  verifyAccessToken(rawToken: string): Promise<OidcAuthData | undefined>;
98
+ /**
99
+ * Verifies a JWT-format access token issued by THIS provider for one of its registered resource
100
+ * servers, and builds the same {@link OidcAuthData} shape the opaque path produces.
101
+ *
102
+ * `sub` is the `accountId` oidc-provider stamped at issuance, which IS the Firebase uid (the
103
+ * opaque path reads the identical value off `accessToken.accountId`), so no mapping table is
104
+ * involved.
105
+ *
106
+ * @param rawToken - The raw token, which may not be a JWT at all.
107
+ * @returns The auth context, or `undefined` when the token is not a verifiable JWT from this provider.
108
+ */
109
+ private _verifyJwtAccessToken;
79
110
  /**
80
111
  * Revokes a Grant entry and every grantable token entry that references it.
81
112
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server",
3
- "version": "14.3.0",
3
+ "version": "14.4.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
@@ -58,17 +58,18 @@
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@cantoo/pdf-lib": ">=2.6.5 <2.11.0",
61
- "@dereekb/analytics": "14.3.0",
62
- "@dereekb/calcom": "14.3.0",
63
- "@dereekb/date": "14.3.0",
64
- "@dereekb/dbx-core": "14.3.0",
65
- "@dereekb/discord": "14.3.0",
66
- "@dereekb/firebase": "14.3.0",
67
- "@dereekb/model": "14.3.0",
68
- "@dereekb/nestjs": "14.3.0",
69
- "@dereekb/rxjs": "14.3.0",
70
- "@dereekb/util": "14.3.0",
71
- "@dereekb/zoho": "14.3.0",
61
+ "@dereekb/analytics": "14.4.0",
62
+ "@dereekb/calcom": "14.4.0",
63
+ "@dereekb/date": "14.4.0",
64
+ "@dereekb/dbx-core": "14.4.0",
65
+ "@dereekb/discord": "14.4.0",
66
+ "@dereekb/firebase": "14.4.0",
67
+ "@dereekb/model": "14.4.0",
68
+ "@dereekb/nestjs": "14.4.0",
69
+ "@dereekb/oauth-resource": "14.4.0",
70
+ "@dereekb/rxjs": "14.4.0",
71
+ "@dereekb/util": "14.4.0",
72
+ "@dereekb/zoho": "14.4.0",
72
73
  "@google-cloud/firestore": "^7.11.6",
73
74
  "@google-cloud/storage": "^7.22.0",
74
75
  "@modelcontextprotocol/node": "2.0.0",
@@ -85,6 +86,7 @@
85
86
  "firebase-admin": "^13.10.0",
86
87
  "firebase-functions": "^7.3.2",
87
88
  "firebase-functions-test": "3.5.0",
89
+ "jose": "^6.2.12",
88
90
  "jsonwebtoken": "^9.0.3",
89
91
  "make-error": "^1.3.6",
90
92
  "nanoid": "^6.0.1",