@frontmcp/auth 1.10.16 → 1.11.0-rc.1

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 (175) hide show
  1. package/browser/authorities/authorities.context.mjs +115 -0
  2. package/browser/authorities/authorities.engine.mjs +272 -0
  3. package/browser/authorities/authorities.errors.mjs +59 -0
  4. package/browser/authorities/authorities.evaluator.mjs +225 -0
  5. package/browser/authorities/authorities.metadata-augment.mjs +18 -0
  6. package/browser/authorities/authorities.registry.mjs +112 -0
  7. package/browser/authorities/authorities.schema.mjs +92 -0
  8. package/browser/authorities/authorities.scope-mapping.mjs +30 -0
  9. package/browser/authorities/authorities.validation.mjs +208 -0
  10. package/browser/authorities/index.mjs +43 -0
  11. package/browser/authorization/authorization.class.mjs +252 -0
  12. package/browser/authorization/authorization.types.mjs +64 -0
  13. package/browser/authorization/dcr-client.registry.mjs +222 -0
  14. package/browser/authorization/index.mjs +41 -0
  15. package/browser/authorization/orchestrated.accessor.mjs +86 -0
  16. package/browser/authorization/orchestrated.authorization.mjs +289 -0
  17. package/browser/authorization/public.authorization.mjs +124 -0
  18. package/browser/authorization/transparent.authorization.mjs +130 -0
  19. package/browser/cimd/cimd-redis.cache.mjs +231 -0
  20. package/browser/cimd/cimd.cache.mjs +215 -0
  21. package/browser/cimd/cimd.errors.mjs +142 -0
  22. package/browser/cimd/cimd.logger.mjs +15 -0
  23. package/browser/cimd/cimd.service.mjs +376 -0
  24. package/browser/cimd/cimd.types.mjs +228 -0
  25. package/browser/cimd/cimd.validator.mjs +217 -0
  26. package/browser/cimd/index.mjs +63 -0
  27. package/browser/common/auth-logger.interface.mjs +14 -0
  28. package/browser/common/index.mjs +6 -0
  29. package/browser/common/jwt.types.mjs +38 -0
  30. package/browser/common/session-user.types.mjs +0 -0
  31. package/browser/common/session.types.mjs +58 -0
  32. package/browser/common/zod-utils.mjs +0 -0
  33. package/browser/consent/consent.types.mjs +94 -0
  34. package/browser/consent/index.mjs +17 -0
  35. package/browser/context/frontmcp-auth-context.factory.mjs +29 -0
  36. package/browser/context/frontmcp-auth-context.impl.mjs +112 -0
  37. package/browser/context/index.mjs +7 -0
  38. package/browser/detection/auth-provider-detection.mjs +176 -0
  39. package/browser/detection/index.mjs +19 -0
  40. package/browser/errors/auth-internal.error.mjs +42 -0
  41. package/browser/errors/auth-internal.errors.mjs +150 -0
  42. package/browser/errors/index.mjs +53 -0
  43. package/browser/fetch/fetch-credential-middleware.mjs +91 -0
  44. package/browser/fetch/index.mjs +19 -0
  45. package/browser/index.mjs +573 -0
  46. package/browser/jwks/index.mjs +9 -0
  47. package/browser/jwks/jose.loader.mjs +28 -0
  48. package/browser/jwks/jwks.service.mjs +521 -0
  49. package/browser/jwks/jwks.utils.mjs +33 -0
  50. package/browser/options/app-auth.schema.mjs +18 -0
  51. package/browser/options/index.mjs +89 -0
  52. package/browser/options/orchestrated.schema.mjs +128 -0
  53. package/browser/options/public.schema.mjs +39 -0
  54. package/browser/options/schema.mjs +16 -0
  55. package/browser/options/shared.schemas.mjs +506 -0
  56. package/browser/options/static.schema.mjs +41 -0
  57. package/browser/options/transparent.schema.mjs +43 -0
  58. package/browser/options/utils.mjs +47 -0
  59. package/browser/people/index.mjs +15 -0
  60. package/browser/people/loopback-token.auth.mjs +115 -0
  61. package/browser/people/people-auth.options.mjs +37 -0
  62. package/browser/session/authorization-vault.mjs +279 -0
  63. package/browser/session/authorization.store.mjs +336 -0
  64. package/browser/session/consent.store.mjs +34 -0
  65. package/browser/session/credential-resume-link.mjs +43 -0
  66. package/browser/session/credentials-accessor.impl.mjs +54 -0
  67. package/browser/session/credentials-accessor.mjs +5 -0
  68. package/browser/session/encrypted-authorization-vault.mjs +405 -0
  69. package/browser/session/federated-auth.session.mjs +176 -0
  70. package/browser/session/incremental-auth-ticket.mjs +42 -0
  71. package/browser/session/index.mjs +266 -0
  72. package/browser/session/orchestrated-token.crypto.mjs +47 -0
  73. package/browser/session/orchestrated-token.store.mjs +286 -0
  74. package/browser/session/pending-login.mjs +37 -0
  75. package/browser/session/redis-session.store.mjs +255 -0
  76. package/browser/session/secure-store-accessor.impl.mjs +78 -0
  77. package/browser/session/secure-store-accessor.mjs +5 -0
  78. package/browser/session/secure-store-backends.mjs +111 -0
  79. package/browser/session/secure-store.factory.mjs +77 -0
  80. package/browser/session/session-credential-vault.factory.mjs +18 -0
  81. package/browser/session/session-credential-vault.mjs +243 -0
  82. package/browser/session/session-crypto.mjs +39 -0
  83. package/browser/session/session-rate-limiter.mjs +126 -0
  84. package/browser/session/session.transport.mjs +16 -0
  85. package/browser/session/signin-binding.mjs +30 -0
  86. package/browser/session/storage/in-memory-authorization-vault.mjs +28 -0
  87. package/browser/session/storage/index.mjs +14 -0
  88. package/browser/session/storage/storage-authorization-vault.mjs +301 -0
  89. package/browser/session/storage/storage-token-store.mjs +83 -0
  90. package/browser/session/storage-authorization.store.mjs +134 -0
  91. package/browser/session/storage-consent.store.mjs +33 -0
  92. package/browser/session/storage-federated-auth.session.mjs +55 -0
  93. package/browser/session/storage-orchestrated-token.store.mjs +197 -0
  94. package/browser/session/token-storage.factory.mjs +58 -0
  95. package/browser/session/token.refresh.mjs +36 -0
  96. package/browser/session/token.vault.mjs +61 -0
  97. package/browser/session/transport-session.types.mjs +108 -0
  98. package/browser/session/utils/auth-token.utils.mjs +58 -0
  99. package/browser/session/utils/index.mjs +23 -0
  100. package/browser/session/utils/session-crypto.utils.mjs +49 -0
  101. package/browser/session/utils/tiny-ttl-cache.mjs +46 -0
  102. package/browser/session/vault-encryption.mjs +187 -0
  103. package/browser/session/vercel-kv-session.store.mjs +230 -0
  104. package/browser/shared-server/index.mjs +17 -0
  105. package/browser/shared-server/shared-server-identity.mjs +55 -0
  106. package/browser/ui/base-layout.mjs +184 -0
  107. package/browser/ui/index.mjs +51 -0
  108. package/browser/ui/local-login.helper.mjs +46 -0
  109. package/browser/ui/templates.mjs +482 -0
  110. package/browser/utils/audience.validator.mjs +110 -0
  111. package/browser/utils/authorization-id.utils.mjs +10 -0
  112. package/browser/utils/index.mjs +45 -0
  113. package/browser/utils/redirect-uri.utils.mjs +22 -0
  114. package/browser/utils/scope-grant.utils.mjs +36 -0
  115. package/browser/utils/token-scopes.utils.mjs +12 -0
  116. package/browser/utils/www-authenticate.utils.mjs +164 -0
  117. package/browser/vault/auth-providers.accessor.impl.mjs +236 -0
  118. package/browser/vault/auth-providers.accessor.mjs +5 -0
  119. package/browser/vault/auth-providers.registry.mjs +140 -0
  120. package/browser/vault/auth-providers.types.mjs +47 -0
  121. package/browser/vault/auth-providers.vault.mjs +206 -0
  122. package/browser/vault/credential-cache.mjs +187 -0
  123. package/browser/vault/credential-helpers.mjs +15 -0
  124. package/browser/vault/credential-loaders/eager-loader.mjs +91 -0
  125. package/browser/vault/credential-loaders/lazy-loader.mjs +120 -0
  126. package/browser/vault/index.mjs +35 -0
  127. package/cimd/cimd.types.d.ts +1 -1
  128. package/cimd/cimd.types.d.ts.map +1 -1
  129. package/common/jwt.types.d.ts +1 -1
  130. package/common/jwt.types.d.ts.map +1 -1
  131. package/common/session.types.d.ts +9 -1
  132. package/common/session.types.d.ts.map +1 -1
  133. package/consent/consent.types.d.ts +1 -1
  134. package/consent/consent.types.d.ts.map +1 -1
  135. package/detection/auth-provider-detection.d.ts +1 -1
  136. package/detection/auth-provider-detection.d.ts.map +1 -1
  137. package/errors/auth-internal.errors.d.ts +6 -0
  138. package/errors/auth-internal.errors.d.ts.map +1 -1
  139. package/errors/index.d.ts +1 -1
  140. package/errors/index.d.ts.map +1 -1
  141. package/esm/index.mjs +2 -2
  142. package/esm/package.json +21 -5
  143. package/index.d.ts +5 -1
  144. package/index.d.ts.map +1 -1
  145. package/index.js +2 -2
  146. package/options/app-auth.schema.d.ts +19 -1
  147. package/options/app-auth.schema.d.ts.map +1 -1
  148. package/options/orchestrated.schema.d.ts +37 -1
  149. package/options/orchestrated.schema.d.ts.map +1 -1
  150. package/options/public.schema.d.ts +1 -1
  151. package/options/public.schema.d.ts.map +1 -1
  152. package/options/schema.d.ts +19 -1
  153. package/options/schema.d.ts.map +1 -1
  154. package/options/shared.schemas.d.ts +10 -14
  155. package/options/shared.schemas.d.ts.map +1 -1
  156. package/options/static.schema.d.ts +1 -1
  157. package/options/static.schema.d.ts.map +1 -1
  158. package/options/transparent.schema.d.ts +1 -1
  159. package/options/transparent.schema.d.ts.map +1 -1
  160. package/package.json +21 -5
  161. package/people/index.d.ts +3 -0
  162. package/people/index.d.ts.map +1 -0
  163. package/people/loopback-token.auth.d.ts +75 -0
  164. package/people/loopback-token.auth.d.ts.map +1 -0
  165. package/people/people-auth.options.d.ts +36 -0
  166. package/people/people-auth.options.d.ts.map +1 -0
  167. package/session/authorization-vault.d.ts +1 -1
  168. package/session/authorization-vault.d.ts.map +1 -1
  169. package/session/encrypted-authorization-vault.d.ts +1 -1
  170. package/session/encrypted-authorization-vault.d.ts.map +1 -1
  171. package/session/secure-store.factory.d.ts.map +1 -1
  172. package/shared-server/index.d.ts +3 -0
  173. package/shared-server/index.d.ts.map +1 -0
  174. package/shared-server/shared-server-identity.d.ts +26 -0
  175. package/shared-server/shared-server-identity.d.ts.map +1 -0
@@ -0,0 +1,176 @@
1
+ // libs/auth/src/detection/auth-provider-detection.ts
2
+ import { internalZ as z } from "@frontmcp/lazy-zod";
3
+ import { staticAuthOptionsSchema } from "../options/static.schema.mjs";
4
+ import {
5
+ isOrchestratedMode,
6
+ isOrchestratedRemote,
7
+ isPublicMode,
8
+ isStaticMode,
9
+ isTransparentMode
10
+ } from "../options/utils.mjs";
11
+ var detectedAuthProviderSchema = z.object({
12
+ id: z.string(),
13
+ providerUrl: z.string().optional(),
14
+ mode: z.enum(["public", "static", "transparent", "local", "remote"]),
15
+ appIds: z.array(z.string()),
16
+ scopes: z.array(z.string()),
17
+ isParentProvider: z.boolean()
18
+ });
19
+ var authProviderDetectionResultSchema = z.object({
20
+ providers: z.map(z.string(), detectedAuthProviderSchema),
21
+ requiresOrchestration: z.boolean(),
22
+ parentProviderId: z.string().optional(),
23
+ childProviderIds: z.array(z.string()),
24
+ uniqueProviderCount: z.number(),
25
+ validationErrors: z.array(z.string()),
26
+ warnings: z.array(z.string())
27
+ });
28
+ function deriveProviderId(options) {
29
+ if (isPublicMode(options)) {
30
+ return options.issuer ?? "public";
31
+ }
32
+ if (isTransparentMode(options)) {
33
+ return options.providerConfig?.id ?? urlToProviderId(options.provider);
34
+ }
35
+ if (isOrchestratedMode(options)) {
36
+ if (isOrchestratedRemote(options)) {
37
+ return options.providerConfig?.id ?? urlToProviderId(options.provider);
38
+ }
39
+ return options.local?.issuer ?? "local";
40
+ }
41
+ return "unknown";
42
+ }
43
+ function urlToProviderId(url) {
44
+ try {
45
+ const parsed = new URL(url);
46
+ return parsed.hostname.replace(/\./g, "_");
47
+ } catch {
48
+ return url.replace(/[^a-zA-Z0-9]/g, "_");
49
+ }
50
+ }
51
+ function extractScopes(options) {
52
+ if (isTransparentMode(options)) {
53
+ return options.requiredScopes || [];
54
+ }
55
+ if (isOrchestratedMode(options)) {
56
+ if (isOrchestratedRemote(options)) {
57
+ return options.scopes || [];
58
+ }
59
+ }
60
+ return [];
61
+ }
62
+ function detectAuthProviders(parentAuth, apps) {
63
+ const providers = /* @__PURE__ */ new Map();
64
+ const validationErrors = [];
65
+ const warnings = [];
66
+ let parentProviderId;
67
+ if (parentAuth) {
68
+ parentProviderId = deriveProviderId(parentAuth);
69
+ providers.set(parentProviderId, {
70
+ id: parentProviderId,
71
+ providerUrl: getProviderUrl(parentAuth),
72
+ mode: parentAuth.mode,
73
+ appIds: ["__parent__"],
74
+ scopes: extractScopes(parentAuth),
75
+ isParentProvider: true
76
+ });
77
+ }
78
+ for (const app of apps) {
79
+ if (!app.auth) {
80
+ continue;
81
+ }
82
+ const providerId = deriveProviderId(app.auth);
83
+ const existing = providers.get(providerId);
84
+ if (existing) {
85
+ existing.appIds.push(app.id);
86
+ const newScopes = extractScopes(app.auth);
87
+ existing.scopes = [.../* @__PURE__ */ new Set([...existing.scopes, ...newScopes])];
88
+ } else {
89
+ providers.set(providerId, {
90
+ id: providerId,
91
+ providerUrl: getProviderUrl(app.auth),
92
+ mode: app.auth.mode,
93
+ appIds: [app.id],
94
+ scopes: extractScopes(app.auth),
95
+ isParentProvider: false
96
+ });
97
+ }
98
+ }
99
+ const childProviderIds = [...providers.keys()].filter((id) => id !== parentProviderId);
100
+ const uniqueProviderCount = providers.size;
101
+ const hasMultipleProviders = uniqueProviderCount > 1;
102
+ const hasChildOnlyProviders = childProviderIds.length > 0 && !parentProviderId;
103
+ const requiresOrchestration = hasMultipleProviders || hasChildOnlyProviders || childProviderIds.length > 0 && parentProviderId !== void 0;
104
+ if (requiresOrchestration && parentAuth && isTransparentMode(parentAuth)) {
105
+ validationErrors.push(
106
+ `Invalid auth configuration: Parent uses transparent mode but apps have their own auth providers. Transparent mode passes tokens through without modification, which is incompatible with multi-provider setups. Change parent auth to local or remote mode to properly manage tokens for each provider. Detected providers: ${[...providers.keys()].join(", ")}`
107
+ );
108
+ }
109
+ const sharedEndpointUnenforced = !parentAuth || isPublicMode(parentAuth) || isStaticMode(parentAuth);
110
+ const unenforcedAppIds = apps.filter((app) => app.auth && !isPublicMode(app.auth) && !staticParentEnforces(parentAuth, app.auth)).map((app) => app.id);
111
+ if (sharedEndpointUnenforced && unenforcedAppIds.length > 0) {
112
+ validationErrors.push(
113
+ `App-level auth is not enforced on the shared endpoint of a server in ${parentAuth?.mode ?? "public"} mode, so the tools of ${unenforcedAppIds.join(", ")} would be served without it. Serve the app on its own endpoint with standalone: true or splitByApp: true, or run the server in local or remote mode with incrementalAuth enabled, which checks each tool call against the apps the caller has authorized (without incrementalAuth, local and remote mode do not check app grants per tool call).`
114
+ );
115
+ }
116
+ const tokenMintingAppIds = apps.filter((app) => app.remoteAuthMode === "forward" && !(parentAuth && isTransparentMode(parentAuth))).map((app) => app.id);
117
+ if (tokenMintingAppIds.length > 0) {
118
+ validationErrors.push(
119
+ `remoteAuth: { mode: 'forward' } on ${tokenMintingAppIds.join(", ")} would send the remote a token this server minted or holds itself: only a server in transparent mode receives its callers' tokens from the identity provider. Use remoteAuth: { mode: 'static', credentials } (or transportOptions.headers) for the remote, or run the server in transparent mode.`
120
+ );
121
+ }
122
+ return {
123
+ providers,
124
+ requiresOrchestration,
125
+ parentProviderId,
126
+ childProviderIds,
127
+ uniqueProviderCount,
128
+ validationErrors,
129
+ warnings
130
+ };
131
+ }
132
+ function staticParentEnforces(parentAuth, appAuth) {
133
+ if (!parentAuth || !isStaticMode(parentAuth) || !isStaticMode(appAuth)) return false;
134
+ const parent = staticAuthOptionsSchema.safeParse(parentAuth);
135
+ const app = staticAuthOptionsSchema.safeParse(appAuth);
136
+ if (!parent.success || !app.success) return false;
137
+ const sameChallenge = parent.data.header.toLowerCase() === app.data.header.toLowerCase() && parent.data.scheme === app.data.scheme;
138
+ return sameChallenge && parent.data.tokens.every((token) => app.data.tokens.includes(token));
139
+ }
140
+ function getProviderUrl(options) {
141
+ if (isTransparentMode(options)) {
142
+ return options.provider;
143
+ }
144
+ if (isOrchestratedMode(options) && isOrchestratedRemote(options)) {
145
+ return options.provider;
146
+ }
147
+ return void 0;
148
+ }
149
+ function appRequiresOrchestration(appAuth, parentAuth) {
150
+ if (!appAuth) {
151
+ return false;
152
+ }
153
+ if (!parentAuth) {
154
+ return appAuth.mode !== "public";
155
+ }
156
+ const appProviderId = deriveProviderId(appAuth);
157
+ const parentProviderId = deriveProviderId(parentAuth);
158
+ return appProviderId !== parentProviderId;
159
+ }
160
+ function getProviderScopes(detection, providerId) {
161
+ const provider = detection.providers.get(providerId);
162
+ return provider?.scopes ?? [];
163
+ }
164
+ function getProviderApps(detection, providerId) {
165
+ const provider = detection.providers.get(providerId);
166
+ return provider?.appIds.filter((id) => id !== "__parent__") ?? [];
167
+ }
168
+ export {
169
+ appRequiresOrchestration,
170
+ authProviderDetectionResultSchema,
171
+ deriveProviderId,
172
+ detectAuthProviders,
173
+ detectedAuthProviderSchema,
174
+ getProviderApps,
175
+ getProviderScopes
176
+ };
@@ -0,0 +1,19 @@
1
+ // libs/auth/src/detection/index.ts
2
+ import {
3
+ detectedAuthProviderSchema,
4
+ authProviderDetectionResultSchema,
5
+ detectAuthProviders,
6
+ deriveProviderId,
7
+ appRequiresOrchestration,
8
+ getProviderScopes,
9
+ getProviderApps
10
+ } from "./auth-provider-detection.mjs";
11
+ export {
12
+ appRequiresOrchestration,
13
+ authProviderDetectionResultSchema,
14
+ deriveProviderId,
15
+ detectAuthProviders,
16
+ detectedAuthProviderSchema,
17
+ getProviderApps,
18
+ getProviderScopes
19
+ };
@@ -0,0 +1,42 @@
1
+ // libs/auth/src/errors/auth-internal.error.ts
2
+ import { randomBytes, bytesToHex } from "@frontmcp/utils";
3
+ var AuthInternalError = class extends Error {
4
+ /**
5
+ * Unique error ID for tracking in logs.
6
+ */
7
+ errorId;
8
+ /**
9
+ * Whether this error should expose details to the client.
10
+ */
11
+ isPublic = false;
12
+ /**
13
+ * HTTP status code equivalent.
14
+ */
15
+ statusCode = 500;
16
+ /**
17
+ * Error code for categorization.
18
+ */
19
+ code;
20
+ constructor(message, code = "AUTH_INTERNAL_ERROR") {
21
+ super(message);
22
+ this.name = this.constructor.name;
23
+ this.code = code;
24
+ this.errorId = `err_${bytesToHex(randomBytes(8))}`;
25
+ Error.captureStackTrace(this, this.constructor);
26
+ }
27
+ /**
28
+ * Get the public-facing error message.
29
+ */
30
+ getPublicMessage() {
31
+ return `Internal auth error. Please contact support with error ID: ${this.errorId}`;
32
+ }
33
+ /**
34
+ * Get the internal error message (for logging).
35
+ */
36
+ getInternalMessage() {
37
+ return this.message;
38
+ }
39
+ };
40
+ export {
41
+ AuthInternalError
42
+ };
@@ -0,0 +1,150 @@
1
+ // libs/auth/src/errors/auth-internal.errors.ts
2
+ import { AuthInternalError } from "./auth-internal.error.mjs";
3
+ var EncryptionContextNotSetError = class extends AuthInternalError {
4
+ constructor() {
5
+ super("Encryption context is not set", "ENCRYPTION_CONTEXT_NOT_SET");
6
+ }
7
+ };
8
+ var VaultLoadError = class extends AuthInternalError {
9
+ originalError;
10
+ constructor(vaultId, originalError) {
11
+ super(`Failed to load vault "${vaultId}"${originalError ? `: ${originalError.message}` : ""}`, "VAULT_LOAD_ERROR");
12
+ this.originalError = originalError;
13
+ }
14
+ };
15
+ var VaultNotFoundError = class extends AuthInternalError {
16
+ constructor(entityType, id) {
17
+ super(`${entityType} "${id}" not found in vault`, "VAULT_NOT_FOUND");
18
+ }
19
+ };
20
+ var TokenNotAvailableError = class extends AuthInternalError {
21
+ constructor(message) {
22
+ super(message, "TOKEN_NOT_AVAILABLE");
23
+ }
24
+ };
25
+ var TokenStoreRequiredError = class extends AuthInternalError {
26
+ constructor(context) {
27
+ super(`Token store is required for ${context}`, "TOKEN_STORE_REQUIRED");
28
+ }
29
+ };
30
+ var NoProviderIdError = class extends AuthInternalError {
31
+ constructor(message) {
32
+ super(message, "NO_PROVIDER_ID");
33
+ }
34
+ };
35
+ var TokenLeakDetectedError = class extends AuthInternalError {
36
+ constructor(detail) {
37
+ super(`Token leak detected: ${detail}`, "TOKEN_LEAK_DETECTED");
38
+ }
39
+ };
40
+ var SessionSecretRequiredError = class extends AuthInternalError {
41
+ constructor(component) {
42
+ super(`Session secret is required for ${component}`, "SESSION_SECRET_REQUIRED");
43
+ }
44
+ };
45
+ var JwtSecretRequiredError = class extends AuthInternalError {
46
+ constructor(mode) {
47
+ super(
48
+ `JWT_SECRET is required in production for auth.mode "${mode}". Without it the server signs tokens with a random per-process secret, so every restart invalidates outstanding tokens and any second instance or isolate rejects tokens the first one minted.`,
49
+ "JWT_SECRET_REQUIRED"
50
+ );
51
+ }
52
+ };
53
+ var JwtSecretWeakError = class extends AuthInternalError {
54
+ constructor(byteLength) {
55
+ super(
56
+ `JWT_SECRET is ${byteLength} bytes; HS256 requires at least 32 (RFC 7518 \xA73.2). A shorter secret is guessable, and whoever guesses it can forge tokens for this server. Generate one with \`openssl rand -hex 32\`.`,
57
+ "JWT_SECRET_INVALID"
58
+ );
59
+ }
60
+ };
61
+ var CredentialProviderAlreadyRegisteredError = class extends AuthInternalError {
62
+ constructor(name) {
63
+ super(`Credential provider "${name}" is already registered`, "CREDENTIAL_PROVIDER_ALREADY_REGISTERED");
64
+ }
65
+ };
66
+ var AuthProvidersNotConfiguredError = class extends AuthInternalError {
67
+ constructor() {
68
+ super("Auth providers are not configured", "AUTH_PROVIDERS_NOT_CONFIGURED");
69
+ }
70
+ };
71
+ var OrchestratedAuthNotAvailableError = class extends AuthInternalError {
72
+ constructor() {
73
+ super("Orchestrated auth is not available", "ORCHESTRATED_AUTH_NOT_AVAILABLE");
74
+ }
75
+ };
76
+ var EncryptionKeyNotConfiguredError = class extends AuthInternalError {
77
+ constructor() {
78
+ super("Encryption key is not configured", "ENCRYPTION_KEY_NOT_CONFIGURED");
79
+ }
80
+ };
81
+ var SessionIdEmptyError = class extends AuthInternalError {
82
+ constructor(storeName) {
83
+ super(`Session ID must not be empty (${storeName})`, "SESSION_ID_EMPTY");
84
+ }
85
+ };
86
+ var ElicitationSecretRequiredError = class extends AuthInternalError {
87
+ constructor() {
88
+ super("Elicitation secret is required", "ELICITATION_SECRET_REQUIRED");
89
+ }
90
+ };
91
+ var ScopeDeniedError = class extends AuthInternalError {
92
+ constructor(providerId) {
93
+ super(`Scope access denied for provider "${providerId}"`, "SCOPE_DENIED");
94
+ }
95
+ };
96
+ var InMemoryStoreRequiredError = class extends AuthInternalError {
97
+ constructor(component) {
98
+ super(`In-memory store is required for ${component}`, "INMEMORY_STORE_REQUIRED");
99
+ }
100
+ };
101
+ var OrchestratorJwksNotAvailableError = class extends AuthInternalError {
102
+ constructor() {
103
+ super("Orchestrator JWKS is not available", "ORCHESTRATOR_JWKS_NOT_AVAILABLE");
104
+ }
105
+ };
106
+ var SecureStoreConfigError = class extends AuthInternalError {
107
+ constructor(message) {
108
+ super(`Invalid auth.secureStore: ${message}`, "SECURE_STORE_CONFIG_INVALID");
109
+ }
110
+ };
111
+ var AuthInvalidInputError = class extends AuthInternalError {
112
+ constructor(message) {
113
+ super(message, "AUTH_INVALID_INPUT");
114
+ }
115
+ };
116
+ var CredentialStorageError = class extends AuthInternalError {
117
+ constructor(message) {
118
+ super(message, "CREDENTIAL_STORAGE_ERROR");
119
+ }
120
+ };
121
+ var AuthFlowError = class extends AuthInternalError {
122
+ constructor(message, code = "AUTH_FLOW_ERROR") {
123
+ super(message, code);
124
+ }
125
+ };
126
+ export {
127
+ AuthFlowError,
128
+ AuthInvalidInputError,
129
+ AuthProvidersNotConfiguredError,
130
+ CredentialProviderAlreadyRegisteredError,
131
+ CredentialStorageError,
132
+ ElicitationSecretRequiredError,
133
+ EncryptionContextNotSetError,
134
+ EncryptionKeyNotConfiguredError,
135
+ InMemoryStoreRequiredError,
136
+ JwtSecretRequiredError,
137
+ JwtSecretWeakError,
138
+ NoProviderIdError,
139
+ OrchestratedAuthNotAvailableError,
140
+ OrchestratorJwksNotAvailableError,
141
+ ScopeDeniedError,
142
+ SecureStoreConfigError,
143
+ SessionIdEmptyError,
144
+ SessionSecretRequiredError,
145
+ TokenLeakDetectedError,
146
+ TokenNotAvailableError,
147
+ TokenStoreRequiredError,
148
+ VaultLoadError,
149
+ VaultNotFoundError
150
+ };
@@ -0,0 +1,53 @@
1
+ // libs/auth/src/errors/index.ts
2
+ import { AuthInternalError } from "./auth-internal.error.mjs";
3
+ import {
4
+ EncryptionContextNotSetError,
5
+ VaultLoadError,
6
+ VaultNotFoundError,
7
+ TokenNotAvailableError,
8
+ TokenStoreRequiredError,
9
+ NoProviderIdError,
10
+ TokenLeakDetectedError,
11
+ JwtSecretRequiredError,
12
+ JwtSecretWeakError,
13
+ SessionSecretRequiredError,
14
+ CredentialProviderAlreadyRegisteredError,
15
+ AuthProvidersNotConfiguredError,
16
+ OrchestratedAuthNotAvailableError,
17
+ EncryptionKeyNotConfiguredError,
18
+ SessionIdEmptyError,
19
+ ElicitationSecretRequiredError,
20
+ ScopeDeniedError,
21
+ InMemoryStoreRequiredError,
22
+ OrchestratorJwksNotAvailableError,
23
+ SecureStoreConfigError,
24
+ AuthInvalidInputError,
25
+ CredentialStorageError,
26
+ AuthFlowError
27
+ } from "./auth-internal.errors.mjs";
28
+ export {
29
+ AuthFlowError,
30
+ AuthInternalError,
31
+ AuthInvalidInputError,
32
+ AuthProvidersNotConfiguredError,
33
+ CredentialProviderAlreadyRegisteredError,
34
+ CredentialStorageError,
35
+ ElicitationSecretRequiredError,
36
+ EncryptionContextNotSetError,
37
+ EncryptionKeyNotConfiguredError,
38
+ InMemoryStoreRequiredError,
39
+ JwtSecretRequiredError,
40
+ JwtSecretWeakError,
41
+ NoProviderIdError,
42
+ OrchestratedAuthNotAvailableError,
43
+ OrchestratorJwksNotAvailableError,
44
+ ScopeDeniedError,
45
+ SecureStoreConfigError,
46
+ SessionIdEmptyError,
47
+ SessionSecretRequiredError,
48
+ TokenLeakDetectedError,
49
+ TokenNotAvailableError,
50
+ TokenStoreRequiredError,
51
+ VaultLoadError,
52
+ VaultNotFoundError
53
+ };
@@ -0,0 +1,91 @@
1
+ // libs/auth/src/fetch/fetch-credential-middleware.ts
2
+ var bearerApplier = {
3
+ apply(token, _url, init) {
4
+ const headers = new Headers(init.headers);
5
+ headers.set("Authorization", `Bearer ${token}`);
6
+ return { init: { ...init, headers } };
7
+ }
8
+ };
9
+ function headerApplier(headerName, prefix) {
10
+ return {
11
+ apply(token, _url, init) {
12
+ const headers = new Headers(init.headers);
13
+ headers.set(headerName, prefix ? `${prefix} ${token}` : token);
14
+ return { init: { ...init, headers } };
15
+ }
16
+ };
17
+ }
18
+ function queryApplier(paramName) {
19
+ return {
20
+ apply(token, url, init) {
21
+ const urlObj = new URL(url);
22
+ urlObj.searchParams.set(paramName, token);
23
+ return { init, url: urlObj.toString() };
24
+ }
25
+ };
26
+ }
27
+ var basicApplier = {
28
+ apply(token, _url, init) {
29
+ const headers = new Headers(init.headers);
30
+ const encoded = typeof btoa === "function" ? btoa(token) : Buffer.from(token).toString("base64");
31
+ headers.set("Authorization", `Basic ${encoded}`);
32
+ return { init: { ...init, headers } };
33
+ }
34
+ };
35
+ function isFrontMcpCredentials(creds) {
36
+ return typeof creds === "object" && creds !== null && "provider" in creds && typeof creds.provider === "string" && creds.provider.length > 0;
37
+ }
38
+ function providerHeadersCredentials(resolveHeaders) {
39
+ return {
40
+ async applyCredentials(_url, init) {
41
+ const { credentials, ...cleanInit } = init;
42
+ if (!isFrontMcpCredentials(credentials)) {
43
+ return { init: typeof credentials === "string" ? init : cleanInit };
44
+ }
45
+ const headers = new Headers(cleanInit.headers);
46
+ for (const [name, value] of Object.entries(await resolveHeaders(credentials.provider))) {
47
+ headers.set(name, value);
48
+ }
49
+ return { init: { ...cleanInit, headers } };
50
+ }
51
+ };
52
+ }
53
+ var FetchCredentialMiddleware = class {
54
+ constructor(tokenAccessor, appliers) {
55
+ this.tokenAccessor = tokenAccessor;
56
+ this.appliers = new Map(Object.entries(appliers ?? {}));
57
+ }
58
+ tokenAccessor;
59
+ appliers;
60
+ /**
61
+ * Inspect the `credentials` field. If it references a named provider,
62
+ * resolve the token and delegate to the provider's applier.
63
+ */
64
+ async applyCredentials(url, init) {
65
+ const creds = init.credentials;
66
+ if (!creds || typeof creds === "string") {
67
+ return { init };
68
+ }
69
+ if (!isFrontMcpCredentials(creds)) {
70
+ const { credentials: _removed2, ...rest } = init;
71
+ return { init: rest };
72
+ }
73
+ const token = await this.tokenAccessor.getToken(creds.provider);
74
+ if (!token) {
75
+ const { credentials: _removed2, ...rest } = init;
76
+ return { init: rest };
77
+ }
78
+ const applier = this.appliers.get(creds.provider) ?? bearerApplier;
79
+ const { credentials: _removed, ...cleanInit } = init;
80
+ return applier.apply(token, url, cleanInit);
81
+ }
82
+ };
83
+ export {
84
+ FetchCredentialMiddleware,
85
+ basicApplier,
86
+ bearerApplier,
87
+ headerApplier,
88
+ isFrontMcpCredentials,
89
+ providerHeadersCredentials,
90
+ queryApplier
91
+ };
@@ -0,0 +1,19 @@
1
+ // libs/auth/src/fetch/index.ts
2
+ import {
3
+ FetchCredentialMiddleware,
4
+ providerHeadersCredentials,
5
+ isFrontMcpCredentials,
6
+ bearerApplier,
7
+ basicApplier,
8
+ headerApplier,
9
+ queryApplier
10
+ } from "./fetch-credential-middleware.mjs";
11
+ export {
12
+ FetchCredentialMiddleware,
13
+ basicApplier,
14
+ bearerApplier,
15
+ headerApplier,
16
+ isFrontMcpCredentials,
17
+ providerHeadersCredentials,
18
+ queryApplier
19
+ };