sub-bridge 1.0.0 → 1.0.3

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 (69) hide show
  1. package/.github/workflows/npm-publish.yml +3 -2
  2. package/.release-please-manifest.json +1 -1
  3. package/CHANGELOG.md +16 -0
  4. package/dist/auth/provider.d.ts +1 -0
  5. package/dist/auth/provider.d.ts.map +1 -1
  6. package/dist/auth/provider.js +22 -0
  7. package/dist/auth/provider.js.map +1 -1
  8. package/dist/cli.js +0 -14
  9. package/dist/cli.js.map +1 -1
  10. package/dist/oauth/authorize.d.ts +73 -0
  11. package/dist/oauth/authorize.d.ts.map +1 -0
  12. package/dist/oauth/authorize.js +197 -0
  13. package/dist/oauth/authorize.js.map +1 -0
  14. package/dist/oauth/crypto.d.ts +58 -0
  15. package/dist/oauth/crypto.d.ts.map +1 -0
  16. package/dist/oauth/crypto.js +170 -0
  17. package/dist/oauth/crypto.js.map +1 -0
  18. package/dist/oauth/dcr.d.ts +44 -0
  19. package/dist/oauth/dcr.d.ts.map +1 -0
  20. package/dist/oauth/dcr.js +84 -0
  21. package/dist/oauth/dcr.js.map +1 -0
  22. package/dist/oauth/metadata.d.ts +23 -0
  23. package/dist/oauth/metadata.d.ts.map +1 -0
  24. package/dist/oauth/metadata.js +29 -0
  25. package/dist/oauth/metadata.js.map +1 -0
  26. package/dist/oauth/token.d.ts +29 -0
  27. package/dist/oauth/token.d.ts.map +1 -0
  28. package/dist/oauth/token.js +117 -0
  29. package/dist/oauth/token.js.map +1 -0
  30. package/dist/routes/chat.d.ts.map +1 -1
  31. package/dist/routes/chat.js +128 -15
  32. package/dist/routes/chat.js.map +1 -1
  33. package/dist/routes/oauth.d.ts +13 -0
  34. package/dist/routes/oauth.d.ts.map +1 -0
  35. package/dist/routes/oauth.js +174 -0
  36. package/dist/routes/oauth.js.map +1 -0
  37. package/dist/server.d.ts.map +1 -1
  38. package/dist/server.js +14 -6
  39. package/dist/server.js.map +1 -1
  40. package/dist/tunnel/providers/cloudflare.d.ts.map +1 -1
  41. package/dist/tunnel/providers/cloudflare.js +19 -5
  42. package/dist/tunnel/providers/cloudflare.js.map +1 -1
  43. package/dist/tunnel/registry.d.ts.map +1 -1
  44. package/dist/tunnel/registry.js +75 -9
  45. package/dist/tunnel/registry.js.map +1 -1
  46. package/dist/utils/cloudflared-config.d.ts +2 -0
  47. package/dist/utils/cloudflared-config.d.ts.map +1 -0
  48. package/dist/utils/cloudflared-config.js +116 -0
  49. package/dist/utils/cloudflared-config.js.map +1 -0
  50. package/dist/utils/setup-instructions.d.ts.map +1 -1
  51. package/dist/utils/setup-instructions.js +6 -9
  52. package/dist/utils/setup-instructions.js.map +1 -1
  53. package/index.html +268 -281
  54. package/package.json +6 -2
  55. package/src/cli.ts +0 -14
  56. package/src/routes/chat.ts +3 -0
  57. package/src/server.ts +10 -6
  58. package/src/tunnel/providers/cloudflare.ts +18 -5
  59. package/src/tunnel/registry.ts +79 -8
  60. package/src/utils/cloudflared-config.ts +121 -0
  61. package/src/utils/setup-instructions.ts +6 -9
  62. package/dist/auth/oauth-flow.d.ts +0 -24
  63. package/dist/auth/oauth-flow.d.ts.map +0 -1
  64. package/dist/auth/oauth-flow.js +0 -184
  65. package/dist/auth/oauth-flow.js.map +0 -1
  66. package/dist/auth/oauth-manager.d.ts +0 -13
  67. package/dist/auth/oauth-manager.d.ts.map +0 -1
  68. package/dist/auth/oauth-manager.js +0 -25
  69. package/dist/auth/oauth-manager.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getServerSecret = getServerSecret;
7
+ exports.encrypt = encrypt;
8
+ exports.decrypt = decrypt;
9
+ exports.createAccessToken = createAccessToken;
10
+ exports.decodeAccessToken = decodeAccessToken;
11
+ exports.generateAuthCode = generateAuthCode;
12
+ exports.generateClientId = generateClientId;
13
+ exports.generateClientSecret = generateClientSecret;
14
+ /**
15
+ * Cryptographic utilities for MCP OAuth token encryption
16
+ *
17
+ * Uses AES-256-GCM for authenticated encryption of upstream credentials.
18
+ * Server secret is generated on first run and stored locally.
19
+ */
20
+ const node_crypto_1 = __importDefault(require("node:crypto"));
21
+ const node_fs_1 = __importDefault(require("node:fs"));
22
+ const node_path_1 = __importDefault(require("node:path"));
23
+ const node_os_1 = __importDefault(require("node:os"));
24
+ // ============================================================================
25
+ // Configuration
26
+ // ============================================================================
27
+ const SECRET_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.sub-bridge');
28
+ const SECRET_FILE = node_path_1.default.join(SECRET_DIR, 'secret.key');
29
+ const ALGORITHM = 'aes-256-gcm';
30
+ const IV_LENGTH = 12; // GCM recommended IV length
31
+ const TAG_LENGTH = 16; // GCM auth tag length
32
+ // ============================================================================
33
+ // Server Secret Management
34
+ // ============================================================================
35
+ let cachedSecret = null;
36
+ /**
37
+ * Get or generate the server encryption secret.
38
+ * Secret is 32 bytes (256 bits) for AES-256.
39
+ */
40
+ function getServerSecret() {
41
+ if (cachedSecret)
42
+ return cachedSecret;
43
+ // Try to read existing secret
44
+ try {
45
+ if (node_fs_1.default.existsSync(SECRET_FILE)) {
46
+ const secret = node_fs_1.default.readFileSync(SECRET_FILE);
47
+ if (secret.length === 32) {
48
+ cachedSecret = secret;
49
+ return cachedSecret;
50
+ }
51
+ }
52
+ }
53
+ catch {
54
+ // Will generate new secret
55
+ }
56
+ // Generate new secret
57
+ const secret = node_crypto_1.default.randomBytes(32);
58
+ // Ensure directory exists
59
+ if (!node_fs_1.default.existsSync(SECRET_DIR)) {
60
+ node_fs_1.default.mkdirSync(SECRET_DIR, { recursive: true, mode: 0o700 });
61
+ }
62
+ // Write secret with restrictive permissions
63
+ node_fs_1.default.writeFileSync(SECRET_FILE, secret, { mode: 0o600 });
64
+ cachedSecret = secret;
65
+ return cachedSecret;
66
+ }
67
+ // ============================================================================
68
+ // Encryption / Decryption
69
+ // ============================================================================
70
+ /**
71
+ * Encrypt data using AES-256-GCM.
72
+ * Returns base64url-encoded string: IV + ciphertext + authTag
73
+ */
74
+ function encrypt(data) {
75
+ const secret = getServerSecret();
76
+ const iv = node_crypto_1.default.randomBytes(IV_LENGTH);
77
+ const cipher = node_crypto_1.default.createCipheriv(ALGORITHM, secret, iv);
78
+ const encrypted = Buffer.concat([
79
+ cipher.update(data, 'utf8'),
80
+ cipher.final()
81
+ ]);
82
+ const authTag = cipher.getAuthTag();
83
+ // Combine: IV (12) + encrypted + authTag (16)
84
+ const combined = Buffer.concat([iv, encrypted, authTag]);
85
+ return combined.toString('base64url');
86
+ }
87
+ /**
88
+ * Decrypt data encrypted with encrypt().
89
+ * Throws on invalid/tampered data.
90
+ */
91
+ function decrypt(encryptedData) {
92
+ const secret = getServerSecret();
93
+ const combined = Buffer.from(encryptedData, 'base64url');
94
+ if (combined.length < IV_LENGTH + TAG_LENGTH) {
95
+ throw new Error('Invalid encrypted data: too short');
96
+ }
97
+ const iv = combined.subarray(0, IV_LENGTH);
98
+ const authTag = combined.subarray(combined.length - TAG_LENGTH);
99
+ const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
100
+ const decipher = node_crypto_1.default.createDecipheriv(ALGORITHM, secret, iv);
101
+ decipher.setAuthTag(authTag);
102
+ try {
103
+ const decrypted = Buffer.concat([
104
+ decipher.update(encrypted),
105
+ decipher.final()
106
+ ]);
107
+ return decrypted.toString('utf8');
108
+ }
109
+ catch {
110
+ throw new Error('Decryption failed: invalid or tampered data');
111
+ }
112
+ }
113
+ /**
114
+ * Create an encrypted access token containing upstream credentials.
115
+ * Format: sb1.<encrypted_payload>
116
+ *
117
+ * The "sb1" prefix identifies this as a Sub Bridge v1 token.
118
+ */
119
+ function createAccessToken(payload) {
120
+ const json = JSON.stringify(payload);
121
+ const encrypted = encrypt(json);
122
+ return `sb1.${encrypted}`;
123
+ }
124
+ /**
125
+ * Decode and validate an access token.
126
+ * Returns null if token is invalid or expired.
127
+ */
128
+ function decodeAccessToken(token) {
129
+ if (!token.startsWith('sb1.')) {
130
+ return null;
131
+ }
132
+ try {
133
+ const encrypted = token.slice(4); // Remove "sb1." prefix
134
+ const json = decrypt(encrypted);
135
+ const payload = JSON.parse(json);
136
+ // Validate required fields
137
+ if (payload.iss !== 'sub-bridge')
138
+ return null;
139
+ if (!payload.sub || !payload.aud)
140
+ return null;
141
+ if (!payload.exp || !payload.iat)
142
+ return null;
143
+ // Check expiration
144
+ if (Date.now() > payload.exp * 1000)
145
+ return null;
146
+ return payload;
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ /**
153
+ * Generate a random authorization code.
154
+ */
155
+ function generateAuthCode() {
156
+ return node_crypto_1.default.randomBytes(32).toString('base64url');
157
+ }
158
+ /**
159
+ * Generate a random client ID for DCR.
160
+ */
161
+ function generateClientId() {
162
+ return `sb_${node_crypto_1.default.randomBytes(16).toString('hex')}`;
163
+ }
164
+ /**
165
+ * Generate a random client secret for DCR.
166
+ */
167
+ function generateClientSecret() {
168
+ return node_crypto_1.default.randomBytes(32).toString('base64url');
169
+ }
170
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/oauth/crypto.ts"],"names":[],"mappings":";;;;;AA+BA,0CA4BC;AAUD,0BAcC;AAMD,0BAwBC;AA+BD,8CAIC;AAMD,8CAsBC;AAKD,4CAEC;AAKD,4CAEC;AAKD,oDAEC;AArMD;;;;;GAKG;AACH,8DAAgC;AAChC,sDAAwB;AACxB,0DAA4B;AAC5B,sDAAwB;AAExB,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAA;AACzD,MAAM,WAAW,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;AACvD,MAAM,SAAS,GAAG,aAAa,CAAA;AAC/B,MAAM,SAAS,GAAG,EAAE,CAAA,CAAC,4BAA4B;AACjD,MAAM,UAAU,GAAG,EAAE,CAAA,CAAC,sBAAsB;AAE5C,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E,IAAI,YAAY,GAAkB,IAAI,CAAA;AAEtC;;;GAGG;AACH,SAAgB,eAAe;IAC7B,IAAI,YAAY;QAAE,OAAO,YAAY,CAAA;IAErC,8BAA8B;IAC9B,IAAI,CAAC;QACH,IAAI,iBAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,iBAAE,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;YAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBACzB,YAAY,GAAG,MAAM,CAAA;gBACrB,OAAO,YAAY,CAAA;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IAED,sBAAsB;IACtB,MAAM,MAAM,GAAG,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAErC,0BAA0B;IAC1B,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,iBAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC5D,CAAC;IAED,4CAA4C;IAC5C,iBAAE,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACtD,YAAY,GAAG,MAAM,CAAA;IACrB,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;GAGG;AACH,SAAgB,OAAO,CAAC,IAAY;IAClC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;IAChC,MAAM,EAAE,GAAG,qBAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;IAExC,MAAM,MAAM,GAAG,qBAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3B,MAAM,CAAC,KAAK,EAAE;KACf,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;IAEnC,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;IACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACvC,CAAC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,aAAqB;IAC3C,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;IAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;IAExD,IAAI,QAAQ,CAAC,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,CAAA;IAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,CAAA;IAE5E,MAAM,QAAQ,GAAG,qBAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IAC/D,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IAE5B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC9B,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;YAC1B,QAAQ,CAAC,KAAK,EAAE;SACjB,CAAC,CAAA;QACF,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;AACH,CAAC;AAyBD;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,OAA8B;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IACpC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,OAAO,OAAO,SAAS,EAAE,CAAA;AAC3B,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,CAAC,uBAAuB;QACxD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA0B,CAAA;QAEzD,2BAA2B;QAC3B,IAAI,OAAO,CAAC,GAAG,KAAK,YAAY;YAAE,OAAO,IAAI,CAAA;QAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAE7C,mBAAmB;QACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI;YAAE,OAAO,IAAI,CAAA;QAEhD,OAAO,OAAO,CAAA;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,OAAO,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACrD,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,OAAO,MAAM,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAA;AACvD,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB;IAClC,OAAO,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACrD,CAAC"}
@@ -0,0 +1,44 @@
1
+ export interface ClientRegistration {
2
+ client_id: string;
3
+ client_secret?: string;
4
+ client_name?: string;
5
+ redirect_uris: string[];
6
+ grant_types: string[];
7
+ response_types: string[];
8
+ token_endpoint_auth_method: string;
9
+ created_at: number;
10
+ }
11
+ export interface RegistrationRequest {
12
+ client_name?: string;
13
+ redirect_uris?: string[];
14
+ grant_types?: string[];
15
+ response_types?: string[];
16
+ token_endpoint_auth_method?: string;
17
+ }
18
+ export interface RegistrationResponse {
19
+ client_id: string;
20
+ client_secret?: string;
21
+ client_name?: string;
22
+ redirect_uris: string[];
23
+ grant_types: string[];
24
+ response_types: string[];
25
+ token_endpoint_auth_method: string;
26
+ client_id_issued_at: number;
27
+ }
28
+ /**
29
+ * Register a new OAuth client.
30
+ */
31
+ export declare function registerClient(request: RegistrationRequest): RegistrationResponse;
32
+ /**
33
+ * Get a registered client by ID.
34
+ */
35
+ export declare function getClient(clientId: string): ClientRegistration | undefined;
36
+ /**
37
+ * Validate client credentials for token endpoint.
38
+ */
39
+ export declare function validateClient(clientId: string, clientSecret?: string): ClientRegistration | null;
40
+ /**
41
+ * Validate redirect URI against registered URIs.
42
+ */
43
+ export declare function validateRedirectUri(clientId: string, redirectUri: string): boolean;
44
+ //# sourceMappingURL=dcr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dcr.d.ts","sourceRoot":"","sources":["../../src/oauth/dcr.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,0BAA0B,EAAE,MAAM,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,0BAA0B,CAAC,EAAE,MAAM,CAAA;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,0BAA0B,EAAE,MAAM,CAAA;IAClC,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,oBAAoB,CA+BjF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE1E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,kBAAkB,GAAG,IAAI,CAe3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAQT"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerClient = registerClient;
4
+ exports.getClient = getClient;
5
+ exports.validateClient = validateClient;
6
+ exports.validateRedirectUri = validateRedirectUri;
7
+ /**
8
+ * Dynamic Client Registration (RFC 7591)
9
+ *
10
+ * Allows MCP clients to register themselves without manual setup.
11
+ * Client registrations are stored in-memory (local-only deployment).
12
+ */
13
+ const crypto_1 = require("./crypto");
14
+ // ============================================================================
15
+ // Client Storage (In-Memory)
16
+ // ============================================================================
17
+ const clients = new Map();
18
+ /**
19
+ * Register a new OAuth client.
20
+ */
21
+ function registerClient(request) {
22
+ const clientId = (0, crypto_1.generateClientId)();
23
+ const clientSecret = request.token_endpoint_auth_method === 'none'
24
+ ? undefined
25
+ : (0, crypto_1.generateClientSecret)();
26
+ const now = Math.floor(Date.now() / 1000);
27
+ const registration = {
28
+ client_id: clientId,
29
+ client_secret: clientSecret,
30
+ client_name: request.client_name,
31
+ redirect_uris: request.redirect_uris || [],
32
+ grant_types: request.grant_types || ['authorization_code'],
33
+ response_types: request.response_types || ['code'],
34
+ token_endpoint_auth_method: request.token_endpoint_auth_method || 'client_secret_post',
35
+ created_at: now,
36
+ };
37
+ clients.set(clientId, registration);
38
+ return {
39
+ client_id: clientId,
40
+ client_secret: clientSecret,
41
+ client_name: registration.client_name,
42
+ redirect_uris: registration.redirect_uris,
43
+ grant_types: registration.grant_types,
44
+ response_types: registration.response_types,
45
+ token_endpoint_auth_method: registration.token_endpoint_auth_method,
46
+ client_id_issued_at: now,
47
+ };
48
+ }
49
+ /**
50
+ * Get a registered client by ID.
51
+ */
52
+ function getClient(clientId) {
53
+ return clients.get(clientId);
54
+ }
55
+ /**
56
+ * Validate client credentials for token endpoint.
57
+ */
58
+ function validateClient(clientId, clientSecret) {
59
+ const client = clients.get(clientId);
60
+ if (!client)
61
+ return null;
62
+ // For public clients (no secret required)
63
+ if (client.token_endpoint_auth_method === 'none') {
64
+ return client;
65
+ }
66
+ // For confidential clients, verify secret
67
+ if (client.client_secret && client.client_secret === clientSecret) {
68
+ return client;
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Validate redirect URI against registered URIs.
74
+ */
75
+ function validateRedirectUri(clientId, redirectUri) {
76
+ const client = clients.get(clientId);
77
+ if (!client)
78
+ return false;
79
+ // If no redirect URIs registered, allow any (for development)
80
+ if (client.redirect_uris.length === 0)
81
+ return true;
82
+ return client.redirect_uris.includes(redirectUri);
83
+ }
84
+ //# sourceMappingURL=dcr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dcr.js","sourceRoot":"","sources":["../../src/oauth/dcr.ts"],"names":[],"mappings":";;AAmDA,wCA+BC;AAKD,8BAEC;AAKD,wCAkBC;AAKD,kDAWC;AAhID;;;;;GAKG;AACH,qCAAiE;AAoCjE,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAA;AAErD;;GAEG;AACH,SAAgB,cAAc,CAAC,OAA4B;IACzD,MAAM,QAAQ,GAAG,IAAA,yBAAgB,GAAE,CAAA;IACnC,MAAM,YAAY,GAAG,OAAO,CAAC,0BAA0B,KAAK,MAAM;QAChE,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAA,6BAAoB,GAAE,CAAA;IAE1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAEzC,MAAM,YAAY,GAAuB;QACvC,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,YAAY;QAC3B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;QAC1C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,oBAAoB,CAAC;QAC1D,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC;QAClD,0BAA0B,EAAE,OAAO,CAAC,0BAA0B,IAAI,oBAAoB;QACtF,UAAU,EAAE,GAAG;KAChB,CAAA;IAED,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAEnC,OAAO;QACL,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,YAAY;QAC3B,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,aAAa,EAAE,YAAY,CAAC,aAAa;QACzC,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,cAAc,EAAE,YAAY,CAAC,cAAc;QAC3C,0BAA0B,EAAE,YAAY,CAAC,0BAA0B;QACnE,mBAAmB,EAAE,GAAG;KACzB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,QAAgB;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAC9B,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,QAAgB,EAChB,YAAqB;IAErB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,0CAA0C;IAC1C,IAAI,MAAM,CAAC,0BAA0B,KAAK,MAAM,EAAE,CAAC;QACjD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,0CAA0C;IAC1C,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,KAAK,YAAY,EAAE,CAAC;QAClE,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,QAAgB,EAChB,WAAmB;IAEnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEzB,8DAA8D;IAC9D,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAElD,OAAO,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACnD,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * OAuth 2.0 Authorization Server Metadata (RFC 8414)
3
+ *
4
+ * Provides the /.well-known/oauth-authorization-server endpoint
5
+ * that MCP clients use to discover OAuth endpoints.
6
+ */
7
+ export interface OAuthMetadata {
8
+ issuer: string;
9
+ authorization_endpoint: string;
10
+ token_endpoint: string;
11
+ registration_endpoint?: string;
12
+ scopes_supported: string[];
13
+ response_types_supported: string[];
14
+ grant_types_supported: string[];
15
+ token_endpoint_auth_methods_supported: string[];
16
+ code_challenge_methods_supported: string[];
17
+ service_documentation?: string;
18
+ }
19
+ /**
20
+ * Generate OAuth metadata for the given issuer URL.
21
+ */
22
+ export declare function getOAuthMetadata(issuerUrl: string): OAuthMetadata;
23
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/oauth/metadata.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,sBAAsB,EAAE,MAAM,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,wBAAwB,EAAE,MAAM,EAAE,CAAA;IAClC,qBAAqB,EAAE,MAAM,EAAE,CAAA;IAC/B,qCAAqC,EAAE,MAAM,EAAE,CAAA;IAC/C,gCAAgC,EAAE,MAAM,EAAE,CAAA;IAC1C,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAgBjE"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 Authorization Server Metadata (RFC 8414)
4
+ *
5
+ * Provides the /.well-known/oauth-authorization-server endpoint
6
+ * that MCP clients use to discover OAuth endpoints.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getOAuthMetadata = getOAuthMetadata;
10
+ /**
11
+ * Generate OAuth metadata for the given issuer URL.
12
+ */
13
+ function getOAuthMetadata(issuerUrl) {
14
+ // Ensure no trailing slash
15
+ const baseUrl = issuerUrl.replace(/\/$/, '');
16
+ return {
17
+ issuer: baseUrl,
18
+ authorization_endpoint: `${baseUrl}/oauth/authorize`,
19
+ token_endpoint: `${baseUrl}/oauth/token`,
20
+ registration_endpoint: `${baseUrl}/oauth/register`,
21
+ scopes_supported: ['openid', 'profile', 'offline_access'],
22
+ response_types_supported: ['code'],
23
+ grant_types_supported: ['authorization_code', 'refresh_token'],
24
+ token_endpoint_auth_methods_supported: ['client_secret_post', 'none'],
25
+ code_challenge_methods_supported: ['S256', 'plain'],
26
+ service_documentation: 'https://github.com/anthropics/sub-bridge',
27
+ };
28
+ }
29
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/oauth/metadata.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAkBH,4CAgBC;AAnBD;;GAEG;AACH,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,2BAA2B;IAC3B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAE5C,OAAO;QACL,MAAM,EAAE,OAAO;QACf,sBAAsB,EAAE,GAAG,OAAO,kBAAkB;QACpD,cAAc,EAAE,GAAG,OAAO,cAAc;QACxC,qBAAqB,EAAE,GAAG,OAAO,iBAAiB;QAClD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,gBAAgB,CAAC;QACzD,wBAAwB,EAAE,CAAC,MAAM,CAAC;QAClC,qBAAqB,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;QAC9D,qCAAqC,EAAE,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACrE,gCAAgC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QACnD,qBAAqB,EAAE,0CAA0C;KAClE,CAAA;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface TokenRequest {
2
+ grant_type: string;
3
+ code?: string;
4
+ redirect_uri?: string;
5
+ client_id?: string;
6
+ client_secret?: string;
7
+ code_verifier?: string;
8
+ refresh_token?: string;
9
+ }
10
+ export interface TokenResponse {
11
+ access_token: string;
12
+ token_type: 'Bearer';
13
+ expires_in: number;
14
+ refresh_token?: string;
15
+ scope?: string;
16
+ }
17
+ export interface TokenError {
18
+ error: string;
19
+ error_description: string;
20
+ }
21
+ /**
22
+ * Process a token request and return an access token or error.
23
+ */
24
+ export declare function processTokenRequest(request: TokenRequest): TokenResponse | TokenError;
25
+ /**
26
+ * Check if a response is an error.
27
+ */
28
+ export declare function isTokenError(response: TokenResponse | TokenError): response is TokenError;
29
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/oauth/token.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,QAAQ,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,YAAY,GACpB,aAAa,GAAG,UAAU,CAc5B;AAuGD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,GAAG,UAAU,GACnC,QAAQ,IAAI,UAAU,CAExB"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processTokenRequest = processTokenRequest;
4
+ exports.isTokenError = isTokenError;
5
+ /**
6
+ * OAuth Token Endpoint
7
+ *
8
+ * Handles token exchange and issues encrypted access tokens
9
+ * containing upstream provider credentials.
10
+ */
11
+ const crypto_1 = require("./crypto");
12
+ const dcr_1 = require("./dcr");
13
+ const authorize_1 = require("./authorize");
14
+ // ============================================================================
15
+ // Token Generation
16
+ // ============================================================================
17
+ const ACCESS_TOKEN_TTL_SECONDS = 3600 * 24 * 7; // 7 days
18
+ /**
19
+ * Process a token request and return an access token or error.
20
+ */
21
+ function processTokenRequest(request) {
22
+ // Validate grant_type
23
+ if (request.grant_type === 'authorization_code') {
24
+ return handleAuthorizationCodeGrant(request);
25
+ }
26
+ if (request.grant_type === 'refresh_token') {
27
+ return handleRefreshTokenGrant(request);
28
+ }
29
+ return {
30
+ error: 'unsupported_grant_type',
31
+ error_description: 'Only authorization_code and refresh_token grants are supported',
32
+ };
33
+ }
34
+ /**
35
+ * Handle authorization_code grant type.
36
+ */
37
+ function handleAuthorizationCodeGrant(request) {
38
+ // Validate required parameters
39
+ if (!request.code) {
40
+ return {
41
+ error: 'invalid_request',
42
+ error_description: 'Missing authorization code',
43
+ };
44
+ }
45
+ if (!request.client_id) {
46
+ return {
47
+ error: 'invalid_request',
48
+ error_description: 'Missing client_id',
49
+ };
50
+ }
51
+ if (!request.redirect_uri) {
52
+ return {
53
+ error: 'invalid_request',
54
+ error_description: 'Missing redirect_uri',
55
+ };
56
+ }
57
+ // Validate client
58
+ const client = (0, dcr_1.validateClient)(request.client_id, request.client_secret);
59
+ if (!client) {
60
+ return {
61
+ error: 'invalid_client',
62
+ error_description: 'Client authentication failed',
63
+ };
64
+ }
65
+ // Exchange authorization code
66
+ const codeResult = (0, authorize_1.exchangeAuthorizationCode)(request.code, request.client_id, request.redirect_uri, request.code_verifier);
67
+ if ('error' in codeResult) {
68
+ return {
69
+ error: codeResult.error,
70
+ error_description: codeResult.errorDescription,
71
+ };
72
+ }
73
+ // Create access token
74
+ return createTokenResponse(codeResult, request.client_id);
75
+ }
76
+ /**
77
+ * Handle refresh_token grant type.
78
+ * For now, we don't support refresh tokens on the Sub Bridge side.
79
+ * Users need to re-authenticate when tokens expire.
80
+ */
81
+ function handleRefreshTokenGrant(_request) {
82
+ // TODO: Implement refresh token support
83
+ // This would require storing refresh tokens securely
84
+ return {
85
+ error: 'unsupported_grant_type',
86
+ error_description: 'Refresh tokens are not yet supported. Please re-authenticate.',
87
+ };
88
+ }
89
+ /**
90
+ * Create a token response from an authorization code.
91
+ */
92
+ function createTokenResponse(authCode, clientId) {
93
+ const now = Math.floor(Date.now() / 1000);
94
+ const expiresAt = now + ACCESS_TOKEN_TTL_SECONDS;
95
+ const payload = {
96
+ iss: 'sub-bridge',
97
+ sub: authCode.userId,
98
+ aud: clientId,
99
+ exp: expiresAt,
100
+ iat: now,
101
+ providers: authCode.providers,
102
+ };
103
+ const accessToken = (0, crypto_1.createAccessToken)(payload);
104
+ return {
105
+ access_token: accessToken,
106
+ token_type: 'Bearer',
107
+ expires_in: ACCESS_TOKEN_TTL_SECONDS,
108
+ scope: 'openid profile',
109
+ };
110
+ }
111
+ /**
112
+ * Check if a response is an error.
113
+ */
114
+ function isTokenError(response) {
115
+ return 'error' in response;
116
+ }
117
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/oauth/token.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,IAAI,EAAW,MAAM,MAAM,CAAA;AA+0BpC,wBAAgB,gBAAgB,+EAsB/B"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,IAAI,EAAW,MAAM,MAAM,CAAA;AA67BpC,wBAAgB,gBAAgB,+EAyB/B"}