@frontmcp/auth 0.0.1 → 0.8.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 (81) hide show
  1. package/README.md +11 -0
  2. package/authorization/authorization.types.d.ts +236 -0
  3. package/authorization/authorization.types.d.ts.map +1 -0
  4. package/authorization/index.d.ts +9 -0
  5. package/authorization/index.d.ts.map +1 -0
  6. package/cimd/cimd-redis.cache.d.ts +111 -0
  7. package/cimd/cimd-redis.cache.d.ts.map +1 -0
  8. package/cimd/cimd.cache.d.ts +200 -0
  9. package/cimd/cimd.cache.d.ts.map +1 -0
  10. package/cimd/cimd.errors.d.ts +124 -0
  11. package/cimd/cimd.errors.d.ts.map +1 -0
  12. package/cimd/cimd.logger.d.ts +39 -0
  13. package/cimd/cimd.logger.d.ts.map +1 -0
  14. package/cimd/cimd.service.d.ts +88 -0
  15. package/cimd/cimd.service.d.ts.map +1 -0
  16. package/cimd/cimd.types.d.ts +178 -0
  17. package/cimd/cimd.types.d.ts.map +1 -0
  18. package/cimd/cimd.validator.d.ts +49 -0
  19. package/cimd/cimd.validator.d.ts.map +1 -0
  20. package/cimd/index.d.ts +17 -0
  21. package/cimd/index.d.ts.map +1 -0
  22. package/esm/index.mjs +4001 -0
  23. package/esm/package.json +59 -0
  24. package/index.d.ts +44 -0
  25. package/index.d.ts.map +1 -0
  26. package/index.js +4131 -0
  27. package/jwks/dev-key-persistence.d.ts +70 -0
  28. package/jwks/dev-key-persistence.d.ts.map +1 -0
  29. package/jwks/index.d.ts +20 -0
  30. package/jwks/index.d.ts.map +1 -0
  31. package/jwks/jwks.service.d.ts +69 -0
  32. package/jwks/jwks.service.d.ts.map +1 -0
  33. package/jwks/jwks.types.d.ts +33 -0
  34. package/jwks/jwks.types.d.ts.map +1 -0
  35. package/jwks/jwks.utils.d.ts +5 -0
  36. package/jwks/jwks.utils.d.ts.map +1 -0
  37. package/package.json +2 -2
  38. package/session/authorization-vault.d.ts +667 -0
  39. package/session/authorization-vault.d.ts.map +1 -0
  40. package/session/authorization.store.d.ts +311 -0
  41. package/session/authorization.store.d.ts.map +1 -0
  42. package/session/index.d.ts +19 -0
  43. package/session/index.d.ts.map +1 -0
  44. package/session/storage/in-memory-authorization-vault.d.ts +53 -0
  45. package/session/storage/in-memory-authorization-vault.d.ts.map +1 -0
  46. package/session/storage/index.d.ts +17 -0
  47. package/session/storage/index.d.ts.map +1 -0
  48. package/session/storage/storage-authorization-vault.d.ts +107 -0
  49. package/session/storage/storage-authorization-vault.d.ts.map +1 -0
  50. package/session/storage/storage-token-store.d.ts +92 -0
  51. package/session/storage/storage-token-store.d.ts.map +1 -0
  52. package/session/token.store.d.ts +39 -0
  53. package/session/token.store.d.ts.map +1 -0
  54. package/session/token.vault.d.ts +33 -0
  55. package/session/token.vault.d.ts.map +1 -0
  56. package/session/utils/index.d.ts +5 -0
  57. package/session/utils/index.d.ts.map +1 -0
  58. package/session/utils/tiny-ttl-cache.d.ts +20 -0
  59. package/session/utils/tiny-ttl-cache.d.ts.map +1 -0
  60. package/session/vault-encryption.d.ts +190 -0
  61. package/session/vault-encryption.d.ts.map +1 -0
  62. package/ui/base-layout.d.ts +170 -0
  63. package/ui/base-layout.d.ts.map +1 -0
  64. package/ui/index.d.ts +10 -0
  65. package/ui/index.d.ts.map +1 -0
  66. package/ui/templates.d.ts +134 -0
  67. package/ui/templates.d.ts.map +1 -0
  68. package/utils/audience.validator.d.ts +130 -0
  69. package/utils/audience.validator.d.ts.map +1 -0
  70. package/utils/index.d.ts +8 -0
  71. package/utils/index.d.ts.map +1 -0
  72. package/utils/www-authenticate.utils.d.ts +98 -0
  73. package/utils/www-authenticate.utils.d.ts.map +1 -0
  74. package/vault/auth-providers.types.d.ts +262 -0
  75. package/vault/auth-providers.types.d.ts.map +1 -0
  76. package/vault/credential-cache.d.ts +98 -0
  77. package/vault/credential-cache.d.ts.map +1 -0
  78. package/vault/credential-helpers.d.ts +14 -0
  79. package/vault/credential-helpers.d.ts.map +1 -0
  80. package/vault/index.d.ts +10 -0
  81. package/vault/index.d.ts.map +1 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Token Store
3
+ *
4
+ * Interface for storing encrypted token blobs.
5
+ *
6
+ * For implementations, use StorageTokenStore with any storage adapter:
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { StorageTokenStore } from '@frontmcp/auth';
11
+ * import { MemoryStorageAdapter, createStorage } from '@frontmcp/utils';
12
+ *
13
+ * // In-memory (development/testing)
14
+ * const memoryAdapter = new MemoryStorageAdapter();
15
+ * await memoryAdapter.connect();
16
+ * const store = new StorageTokenStore(memoryAdapter);
17
+ *
18
+ * // With any backend (Redis, Vercel KV, Upstash)
19
+ * const storage = await createStorage({ type: 'auto' });
20
+ * const store = new StorageTokenStore(storage);
21
+ * ```
22
+ */
23
+ import type { EncBlob } from './token.vault';
24
+ export type SecretRecord = {
25
+ id: string;
26
+ blob: EncBlob;
27
+ updatedAt: number;
28
+ };
29
+ export interface TokenStore {
30
+ /** Create or overwrite a blob under a stable id. */
31
+ put(id: string, blob: EncBlob): Promise<void>;
32
+ /** Fetch encrypted blob by id. */
33
+ get(id: string): Promise<SecretRecord | undefined>;
34
+ /** Delete a reference. */
35
+ del(id: string): Promise<void>;
36
+ /** Allocate a new id (opaque). */
37
+ allocId(): string;
38
+ }
39
+ //# sourceMappingURL=token.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.store.d.ts","sourceRoot":"","sources":["../../src/session/token.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,kCAAkC;IAClC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACnD,0BAA0B;IAC1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,kCAAkC;IAClC,OAAO,IAAI,MAAM,CAAC;CACnB"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Token Vault
3
+ *
4
+ * Secure token encryption/decryption using AES-256-GCM.
5
+ * Supports key rotation for seamless key management.
6
+ */
7
+ export type EncBlob = {
8
+ alg: 'A256GCM';
9
+ kid: string;
10
+ iv: string;
11
+ tag: string;
12
+ data: string;
13
+ exp?: number;
14
+ meta?: Record<string, unknown>;
15
+ };
16
+ export type VaultKey = {
17
+ kid: string;
18
+ key: Uint8Array;
19
+ };
20
+ export declare class TokenVault {
21
+ /** Active key used for new encryptions */
22
+ private active;
23
+ /** All known keys by kid for decryption (includes active) */
24
+ private keys;
25
+ constructor(keys: VaultKey[]);
26
+ rotateTo(k: VaultKey): void;
27
+ encrypt(plaintext: string, opts?: {
28
+ exp?: number;
29
+ meta?: Record<string, unknown>;
30
+ }): Promise<EncBlob>;
31
+ decrypt(blob: EncBlob): Promise<string>;
32
+ }
33
+ //# sourceMappingURL=token.vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.vault.d.ts","sourceRoot":"","sources":["../../src/session/token.vault.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,SAAS,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,CAAA;CAAE,CAAC;AAExD,qBAAa,UAAU;IACrB,0CAA0C;IAC1C,OAAO,CAAC,MAAM,CAAW;IACzB,6DAA6D;IAC7D,OAAO,CAAC,IAAI,CAAiC;gBAEjC,IAAI,EAAE,QAAQ,EAAE;IAwB5B,QAAQ,CAAC,CAAC,EAAE,QAAQ;IASd,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAerG,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;CAmB9C"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Session utilities
3
+ */
4
+ export { TinyTtlCache } from './tiny-ttl-cache';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/session/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Tiny TTL Cache
3
+ *
4
+ * A simple in-memory cache with time-to-live expiration.
5
+ */
6
+ export declare class TinyTtlCache<K, V> {
7
+ private readonly ttlMs;
8
+ private map;
9
+ constructor(ttlMs: number);
10
+ get(k: K): V | undefined;
11
+ set(k: K, v: V): void;
12
+ delete(k: K): boolean;
13
+ clear(): void;
14
+ size(): number;
15
+ /**
16
+ * Remove all expired entries
17
+ */
18
+ cleanup(): number;
19
+ }
20
+ //# sourceMappingURL=tiny-ttl-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiny-ttl-cache.d.ts","sourceRoot":"","sources":["../../../src/session/utils/tiny-ttl-cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC;IAGhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,GAAG,CAAuC;gBAErB,KAAK,EAAE,MAAM;IAE1C,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAUxB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAId,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO;IAIrB,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,OAAO,IAAI,MAAM;CAWlB"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Vault Encryption
3
+ *
4
+ * Client-side key derivation for zero-knowledge credential storage.
5
+ *
6
+ * Security Model:
7
+ * - The JWT authorization token contains a unique `jti` (JWT ID) claim
8
+ * - A secret portion of the token (or a derived key) is used as the encryption key
9
+ * - The server stores encrypted blobs in Redis but CANNOT decrypt them
10
+ * - Only the client presenting the valid JWT can decrypt their vault
11
+ *
12
+ * Key Derivation:
13
+ * - Input: JWT token (after signature verification)
14
+ * - Extract: jti + a secret claim (e.g., `vaultKey` or derived from signature)
15
+ * - Derive: HKDF-SHA256 to produce AES-256 key
16
+ *
17
+ * Encryption:
18
+ * - Algorithm: AES-256-GCM (authenticated encryption)
19
+ * - IV: Random 12 bytes per encryption (stored with ciphertext)
20
+ * - Auth Tag: 16 bytes (ensures integrity)
21
+ */
22
+ import { z } from 'zod';
23
+ /**
24
+ * Encrypted data format stored in Redis
25
+ */
26
+ export declare const encryptedDataSchema: z.ZodObject<{
27
+ v: z.ZodLiteral<1>;
28
+ alg: z.ZodLiteral<"aes-256-gcm">;
29
+ iv: z.ZodString;
30
+ ct: z.ZodString;
31
+ tag: z.ZodString;
32
+ }, z.core.$strip>;
33
+ export type EncryptedData = z.infer<typeof encryptedDataSchema>;
34
+ /**
35
+ * JWT claims required for key derivation
36
+ */
37
+ export interface VaultKeyDerivationClaims {
38
+ /** JWT ID - unique identifier for this token/vault */
39
+ jti: string;
40
+ /** Vault key material - secret claim added during token generation */
41
+ vaultKey?: string;
42
+ /** Subject - user identifier */
43
+ sub: string;
44
+ /** Issued at timestamp */
45
+ iat: number;
46
+ }
47
+ /**
48
+ * Vault encryption configuration
49
+ */
50
+ export interface VaultEncryptionConfig {
51
+ /**
52
+ * Server-side pepper added to key derivation
53
+ * This adds defense-in-depth: even with a stolen JWT,
54
+ * attacker needs the pepper to derive the key
55
+ */
56
+ pepper?: string;
57
+ /**
58
+ * Key derivation info string for HKDF
59
+ * Allows domain separation between different uses
60
+ */
61
+ hkdfInfo?: string;
62
+ }
63
+ /**
64
+ * VaultEncryption handles encryption/decryption of vault credentials
65
+ * using keys derived from the client's JWT authorization token.
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const encryption = new VaultEncryption({ pepper: process.env.VAULT_PEPPER });
70
+ *
71
+ * // After JWT verification, derive the encryption key
72
+ * const key = await encryption.deriveKey(jwtClaims);
73
+ *
74
+ * // Encrypt credentials before storing
75
+ * const encrypted = await encryption.encrypt(JSON.stringify(credentials), key);
76
+ *
77
+ * // Decrypt when reading
78
+ * const decrypted = await encryption.decrypt(encrypted, key);
79
+ * const credentials = JSON.parse(decrypted);
80
+ * ```
81
+ */
82
+ export declare class VaultEncryption {
83
+ private readonly pepper;
84
+ private readonly hkdfInfo;
85
+ constructor(config?: VaultEncryptionConfig);
86
+ /**
87
+ * Derive an encryption key from JWT claims
88
+ *
89
+ * The key derivation uses HKDF:
90
+ * 1. Combine jti + vaultKey + sub + iat + pepper as IKM
91
+ * 2. Apply HKDF-SHA256 to derive a 256-bit key
92
+ *
93
+ * @param claims - JWT claims containing key material
94
+ * @returns 32-byte encryption key as Uint8Array
95
+ */
96
+ deriveKey(claims: VaultKeyDerivationClaims): Promise<Uint8Array>;
97
+ /**
98
+ * Derive a key directly from the raw JWT token string
99
+ *
100
+ * This is useful when you want to derive the key from the token
101
+ * before or without fully parsing the claims. Uses the token's
102
+ * signature portion as additional entropy.
103
+ *
104
+ * @param token - The raw JWT token string
105
+ * @param claims - Parsed JWT claims
106
+ * @returns 32-byte encryption key as Uint8Array
107
+ */
108
+ deriveKeyFromToken(token: string, claims: VaultKeyDerivationClaims): Promise<Uint8Array>;
109
+ /**
110
+ * Encrypt plaintext data using AES-256-GCM
111
+ *
112
+ * @param plaintext - Data to encrypt (typically JSON string)
113
+ * @param key - 32-byte encryption key from deriveKey()
114
+ * @returns Encrypted data object (safe to store in Redis)
115
+ */
116
+ encrypt(plaintext: string, key: Uint8Array): Promise<EncryptedData>;
117
+ /**
118
+ * Decrypt encrypted data using AES-256-GCM
119
+ *
120
+ * @param encrypted - Encrypted data object from encrypt()
121
+ * @param key - 32-byte encryption key from deriveKey()
122
+ * @returns Decrypted plaintext
123
+ * @throws Error if decryption fails (wrong key, tampered data, etc.)
124
+ */
125
+ decrypt(encrypted: EncryptedData, key: Uint8Array): Promise<string>;
126
+ /**
127
+ * Encrypt a JavaScript object (serializes to JSON first)
128
+ *
129
+ * @param data - Object to encrypt
130
+ * @param key - Encryption key
131
+ * @returns Encrypted data
132
+ */
133
+ encryptObject<T>(data: T, key: Uint8Array): Promise<EncryptedData>;
134
+ /**
135
+ * Decrypt and parse a JavaScript object
136
+ *
137
+ * @param encrypted - Encrypted data
138
+ * @param key - Encryption key
139
+ * @returns Decrypted and parsed object
140
+ */
141
+ decryptObject<T>(encrypted: EncryptedData, key: Uint8Array): Promise<T>;
142
+ /**
143
+ * Check if data is in encrypted format
144
+ *
145
+ * @param data - Data to check
146
+ * @returns True if data appears to be encrypted
147
+ */
148
+ isEncrypted(data: unknown): data is EncryptedData;
149
+ }
150
+ /**
151
+ * Vault entry with encrypted credentials
152
+ *
153
+ * The structure separates:
154
+ * - Metadata (unencrypted): id, userSub, timestamps, app lists
155
+ * - Sensitive data (encrypted): provider tokens, app credentials
156
+ */
157
+ export declare const encryptedVaultEntrySchema: z.ZodObject<{
158
+ id: z.ZodString;
159
+ userSub: z.ZodString;
160
+ userEmail: z.ZodOptional<z.ZodString>;
161
+ userName: z.ZodOptional<z.ZodString>;
162
+ clientId: z.ZodString;
163
+ createdAt: z.ZodNumber;
164
+ lastAccessAt: z.ZodNumber;
165
+ encryptedData: z.ZodObject<{
166
+ v: z.ZodLiteral<1>;
167
+ alg: z.ZodLiteral<"aes-256-gcm">;
168
+ iv: z.ZodString;
169
+ ct: z.ZodString;
170
+ tag: z.ZodString;
171
+ }, z.core.$strip>;
172
+ authorizedAppIds: z.ZodArray<z.ZodString>;
173
+ skippedAppIds: z.ZodArray<z.ZodString>;
174
+ pendingAuthIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
175
+ }, z.core.$strip>;
176
+ export type EncryptedVaultEntry = z.infer<typeof encryptedVaultEntrySchema>;
177
+ /**
178
+ * Sensitive data that gets encrypted
179
+ */
180
+ export interface VaultSensitiveData {
181
+ /** App credentials */
182
+ appCredentials: Record<string, unknown>;
183
+ /** Consent record */
184
+ consent?: unknown;
185
+ /** Federated login record */
186
+ federated?: unknown;
187
+ /** Pending auth details (URLs, scopes, etc.) */
188
+ pendingAuths: unknown[];
189
+ }
190
+ //# sourceMappingURL=vault-encryption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-encryption.d.ts","sourceRoot":"","sources":["../../src/session/vault-encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;iBAW9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,MAAM,GAAE,qBAA0B;IAM9C;;;;;;;;;OASG;IACG,SAAS,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;IAkBtE;;;;;;;;;;OAUG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;IAsB9F;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAoBzE;;;;;;;OAOG;IACG,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BzE;;;;;;OAMG;IACG,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAIxE;;;;;;OAMG;IACG,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;IAK7E;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,aAAa;CAGlD;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;iBAuBpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sBAAsB;IACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,YAAY,EAAE,OAAO,EAAE,CAAC;CACzB"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Base Layout for Server-Rendered Pages
3
+ *
4
+ * Provides a consistent HTML shell with all CDN resources pre-configured:
5
+ * - Tailwind CSS v4 (Browser CDN) - Utility-first CSS framework with @theme support
6
+ * - Google Fonts (Inter) - Modern UI typography
7
+ *
8
+ * No build step required - all resources loaded from CDN at runtime.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Basic usage
13
+ * const html = baseLayout('<div>content</div>', { title: 'Page' });
14
+ *
15
+ * // With custom theme
16
+ * const html = baseLayout('<div>content</div>', {
17
+ * title: 'Page',
18
+ * theme: {
19
+ * colors: {
20
+ * primary: '#3b82f6',
21
+ * 'primary-dark': '#2563eb',
22
+ * },
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+ /**
28
+ * CDN URLs and versions - centralized for easy updates
29
+ */
30
+ export declare const CDN: {
31
+ /** Tailwind CSS v4 Browser CDN - generates styles on-the-fly with @theme support */
32
+ readonly tailwind: "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
33
+ /** Google Fonts - Inter for modern UI */
34
+ readonly fonts: {
35
+ readonly preconnect: readonly ["https://fonts.googleapis.com", "https://fonts.gstatic.com"];
36
+ readonly stylesheet: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
37
+ };
38
+ };
39
+ /**
40
+ * Theme color configuration
41
+ * Keys become CSS custom properties: --color-{key}
42
+ */
43
+ export interface ThemeColors {
44
+ /** Primary brand color */
45
+ primary?: string;
46
+ /** Darker primary for hover states */
47
+ 'primary-dark'?: string;
48
+ /** Secondary brand color */
49
+ secondary?: string;
50
+ /** Accent color for highlights */
51
+ accent?: string;
52
+ /** Success state color */
53
+ success?: string;
54
+ /** Warning state color */
55
+ warning?: string;
56
+ /** Error/danger state color */
57
+ danger?: string;
58
+ /** Custom colors (any additional colors) */
59
+ [key: string]: string | undefined;
60
+ }
61
+ /**
62
+ * Theme font configuration
63
+ * Keys become CSS custom properties: --font-{key}
64
+ */
65
+ export interface ThemeFonts {
66
+ /** Sans-serif font family */
67
+ sans?: string;
68
+ /** Serif font family */
69
+ serif?: string;
70
+ /** Monospace font family */
71
+ mono?: string;
72
+ /** Custom fonts */
73
+ [key: string]: string | undefined;
74
+ }
75
+ /**
76
+ * Complete theme configuration for FrontMCP UI
77
+ */
78
+ export interface ThemeConfig {
79
+ /** Custom colors */
80
+ colors?: ThemeColors;
81
+ /** Custom fonts */
82
+ fonts?: ThemeFonts;
83
+ /** Additional custom CSS variables (raw @theme content) */
84
+ customVars?: string;
85
+ /** Additional custom CSS (outside @theme) */
86
+ customCss?: string;
87
+ }
88
+ /**
89
+ * Default theme with FrontMCP branding
90
+ */
91
+ export declare const DEFAULT_THEME: ThemeConfig;
92
+ /**
93
+ * Options for the base layout
94
+ */
95
+ export interface BaseLayoutOptions {
96
+ /** Page title (will be suffixed with " - FrontMCP") */
97
+ title: string;
98
+ /** Optional description for meta tag */
99
+ description?: string;
100
+ /** Include Tailwind CSS (default: true) */
101
+ includeTailwind?: boolean;
102
+ /** Include Google Fonts (default: true) */
103
+ includeFonts?: boolean;
104
+ /** Additional head content (scripts, styles, meta tags) */
105
+ headExtra?: string;
106
+ /** Body classes (default: 'bg-gray-50 min-h-screen font-sans antialiased') */
107
+ bodyClass?: string;
108
+ /** Theme configuration - colors, fonts, and custom CSS */
109
+ theme?: ThemeConfig;
110
+ }
111
+ export { escapeHtml } from '@frontmcp/utils';
112
+ /**
113
+ * Build the complete HTML document with CDN resources
114
+ *
115
+ * @param content - The page content (HTML string)
116
+ * @param options - Layout configuration options
117
+ * @returns Complete HTML document string
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const html = baseLayout('<div>My content</div>', {
122
+ * title: 'Sign In',
123
+ * description: 'Sign in to your account',
124
+ * theme: {
125
+ * colors: {
126
+ * primary: '#ff6b6b',
127
+ * },
128
+ * },
129
+ * });
130
+ * ```
131
+ */
132
+ export declare function baseLayout(content: string, options: BaseLayoutOptions): string;
133
+ /**
134
+ * Create a layout wrapper function with preset options
135
+ *
136
+ * @param defaultOptions - Default options to apply to all pages
137
+ * @returns A function that wraps content with the layout
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const brandedLayout = createLayout({
142
+ * theme: {
143
+ * colors: {
144
+ * primary: '#ff6b6b',
145
+ * 'primary-dark': '#ee5a5a',
146
+ * },
147
+ * },
148
+ * });
149
+ *
150
+ * const html = brandedLayout('<div>Content</div>', { title: 'Page' });
151
+ * ```
152
+ */
153
+ export declare function createLayout(defaultOptions: Partial<BaseLayoutOptions>): (content: string, options: BaseLayoutOptions) => string;
154
+ /**
155
+ * Default auth layout with standard styling
156
+ */
157
+ export declare const authLayout: (content: string, options: BaseLayoutOptions) => string;
158
+ /**
159
+ * Centered card layout for login/auth pages
160
+ */
161
+ export declare function centeredCardLayout(content: string, options: BaseLayoutOptions): string;
162
+ /**
163
+ * Wide layout for consent/selection pages
164
+ */
165
+ export declare function wideLayout(content: string, options: BaseLayoutOptions): string;
166
+ /**
167
+ * Extra wide layout for tool selection pages
168
+ */
169
+ export declare function extraWideLayout(content: string, options: BaseLayoutOptions): string;
170
+ //# sourceMappingURL=base-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-layout.d.ts","sourceRoot":"","sources":["../../src/ui/base-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAQH;;GAEG;AACH,eAAO,MAAM,GAAG;IACd,oFAAoF;;IAGpF,yCAAyC;;;;;CAKjC,CAAC;AAMX;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,mBAAmB;IACnB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,WAa3B,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IAEd,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAOD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAsC7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAkE9E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACzC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,KAAK,MAAM,CAmBzD;AAMD;;GAEG;AACH,eAAO,MAAM,UAAU,YA5BV,MAAM,WAAW,iBAAiB,KAAK,MA8BlD,CAAC;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAYtF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAS9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CASnF"}
package/ui/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Auth UI Module
3
+ *
4
+ * Server-side HTML templates for OAuth authorization flows.
5
+ */
6
+ export { CDN, DEFAULT_THEME, baseLayout, createLayout, authLayout, centeredCardLayout, wideLayout, extraWideLayout, escapeHtml, } from './base-layout';
7
+ export type { ThemeColors, ThemeFonts, ThemeConfig, BaseLayoutOptions } from './base-layout';
8
+ export { buildConsentPage, buildIncrementalAuthPage, buildFederatedLoginPage, buildToolConsentPage, buildLoginPage, buildErrorPage, renderToHtml, } from './templates';
9
+ export type { AppAuthCard, ProviderCard, ToolCard } from './templates';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,GAAG,EACH,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG7F,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Template Builders for OAuth UI
3
+ *
4
+ * Server-side HTML rendering with Tailwind CSS for OAuth authorization flows.
5
+ * No build step required - pure runtime rendering with Tailwind CSS CDN.
6
+ *
7
+ * Features:
8
+ * - OAuth consent page with multiple apps
9
+ * - Incremental authorization page for single app
10
+ * - Federated login page for multi-provider selection
11
+ * - All pages use Tailwind CSS from CDN (no build required)
12
+ * - Google Fonts (Inter) for modern typography
13
+ *
14
+ * Uses base-layout.ts for consistent HTML shell with CDN resources.
15
+ */
16
+ import { escapeHtml as baseEscapeHtml } from './base-layout';
17
+ /**
18
+ * App information for authorization cards
19
+ */
20
+ export interface AppAuthCard {
21
+ /** App identifier */
22
+ appId: string;
23
+ /** Display name */
24
+ appName: string;
25
+ /** App description */
26
+ description?: string;
27
+ /** Icon URL (optional, will use initials fallback) */
28
+ iconUrl?: string;
29
+ /** Scopes required by this app */
30
+ requiredScopes?: string[];
31
+ }
32
+ /**
33
+ * Provider information for federated login
34
+ */
35
+ export interface ProviderCard {
36
+ /** Provider identifier */
37
+ providerId: string;
38
+ /** Display name */
39
+ providerName: string;
40
+ /** Provider URL (for remote providers) */
41
+ providerUrl?: string;
42
+ /** Auth mode */
43
+ mode: string;
44
+ /** App IDs associated with this provider */
45
+ appIds: string[];
46
+ /** Whether this is the parent/primary provider */
47
+ isPrimary?: boolean;
48
+ }
49
+ /**
50
+ * Tool information for consent page
51
+ */
52
+ export interface ToolCard {
53
+ /** Tool identifier */
54
+ toolId: string;
55
+ /** Display name */
56
+ toolName: string;
57
+ /** Tool description */
58
+ description?: string;
59
+ /** Parent app ID */
60
+ appId: string;
61
+ /** Parent app name */
62
+ appName: string;
63
+ }
64
+ /**
65
+ * Escape HTML special characters
66
+ * Re-exported from base-layout for convenience
67
+ */
68
+ export declare const escapeHtml: typeof baseEscapeHtml;
69
+ /**
70
+ * Build OAuth consent page with Tailwind
71
+ * Shows all apps at once with Authorize/Skip buttons
72
+ */
73
+ export declare function buildConsentPage(params: {
74
+ apps: AppAuthCard[];
75
+ clientName: string;
76
+ pendingAuthId: string;
77
+ csrfToken: string;
78
+ callbackPath: string;
79
+ }): string;
80
+ /**
81
+ * Build incremental auth page (single app) with Tailwind
82
+ * Used when a tool requires authorization for a skipped app
83
+ */
84
+ export declare function buildIncrementalAuthPage(params: {
85
+ app: AppAuthCard;
86
+ toolId: string;
87
+ sessionHint: string;
88
+ callbackPath: string;
89
+ }): string;
90
+ /**
91
+ * Build federated login page for multi-provider selection
92
+ */
93
+ export declare function buildFederatedLoginPage(params: {
94
+ providers: ProviderCard[];
95
+ clientName: string;
96
+ pendingAuthId: string;
97
+ callbackPath: string;
98
+ }): string;
99
+ /**
100
+ * Build consent page for tool selection
101
+ */
102
+ export declare function buildToolConsentPage(params: {
103
+ tools: ToolCard[];
104
+ clientName: string;
105
+ pendingAuthId: string;
106
+ csrfToken: string;
107
+ callbackPath: string;
108
+ userName?: string;
109
+ userEmail?: string;
110
+ }): string;
111
+ /**
112
+ * Build simple login page
113
+ */
114
+ export declare function buildLoginPage(params: {
115
+ clientName: string;
116
+ scope: string;
117
+ pendingAuthId: string;
118
+ callbackPath: string;
119
+ }): string;
120
+ /**
121
+ * Build error page
122
+ */
123
+ export declare function buildErrorPage(params: {
124
+ error: string;
125
+ description: string;
126
+ }): string;
127
+ /**
128
+ * Simple wrapper for compatibility - just returns the HTML string
129
+ * (Templates are already complete HTML documents)
130
+ */
131
+ export declare function renderToHtml(html: string, _options?: {
132
+ title?: string;
133
+ }): string;
134
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/ui/templates.ts"],"names":[],"mappings":"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"}