@honeyfield/rent2b-mcp 1.2.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-client.js +25 -9
- package/dist/api-client.js.map +1 -1
- package/dist/auth/api-auth.d.ts +29 -0
- package/dist/auth/api-auth.js +88 -0
- package/dist/auth/api-auth.js.map +1 -0
- package/dist/auth/authorize-page.d.ts +17 -3
- package/dist/auth/authorize-page.js +75 -23
- package/dist/auth/authorize-page.js.map +1 -1
- package/dist/auth/authorize-page.test.js +72 -18
- package/dist/auth/authorize-page.test.js.map +1 -1
- package/dist/auth/http-oauth.d.ts +19 -8
- package/dist/auth/http-oauth.js +132 -18
- package/dist/auth/http-oauth.js.map +1 -1
- package/dist/auth/provider.d.ts +8 -2
- package/dist/auth/provider.js +60 -9
- package/dist/auth/provider.js.map +1 -1
- package/dist/auth/provider.test.js +69 -37
- package/dist/auth/provider.test.js.map +1 -1
- package/dist/auth/social.d.ts +40 -0
- package/dist/auth/social.js +58 -0
- package/dist/auth/social.js.map +1 -0
- package/dist/auth/stores.d.ts +3 -1
- package/dist/auth/stores.js.map +1 -1
- package/dist/auth/stores.test.js +2 -2
- package/dist/auth/stores.test.js.map +1 -1
- package/dist/auth/token-crypto.d.ts +15 -1
- package/dist/auth/token-crypto.js +13 -0
- package/dist/auth/token-crypto.js.map +1 -1
- package/dist/config.d.ts +17 -6
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +28 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { createHash, randomBytes, randomUUID } from 'node:crypto';
|
|
3
|
+
const FLOW_TTL_MS = 10 * 60 * 1000;
|
|
4
|
+
export class SocialFlowStore {
|
|
5
|
+
flows = new Map();
|
|
6
|
+
/** Store a pending flow and return its opaque id. */
|
|
7
|
+
create(flow) {
|
|
8
|
+
const sid = randomUUID().replace(/-/g, '');
|
|
9
|
+
this.flows.set(sid, { ...flow, expiresAt: Date.now() + FLOW_TTL_MS });
|
|
10
|
+
return sid;
|
|
11
|
+
}
|
|
12
|
+
/** Consume a flow exactly once; undefined if unknown or expired. */
|
|
13
|
+
take(sid) {
|
|
14
|
+
const rec = this.flows.get(sid);
|
|
15
|
+
if (!rec)
|
|
16
|
+
return undefined;
|
|
17
|
+
this.flows.delete(sid);
|
|
18
|
+
if (rec.expiresAt < Date.now())
|
|
19
|
+
return undefined;
|
|
20
|
+
return rec;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function generatePkce() {
|
|
24
|
+
const verifier = randomBytes(32).toString('base64url'); // 43-char RFC 7636 verifier
|
|
25
|
+
const challenge = createHash('sha256').update(verifier).digest('base64url');
|
|
26
|
+
return { verifier, challenge };
|
|
27
|
+
}
|
|
28
|
+
export class SupabaseOAuthClient {
|
|
29
|
+
url;
|
|
30
|
+
anonKey;
|
|
31
|
+
constructor(url, anonKey) {
|
|
32
|
+
this.url = url;
|
|
33
|
+
this.anonKey = anonKey;
|
|
34
|
+
}
|
|
35
|
+
/** GoTrue `/authorize` URL to redirect the browser to (matches supabase-js). */
|
|
36
|
+
authorizeUrl(provider, redirectTo, codeChallenge) {
|
|
37
|
+
const u = new URL(`${this.url}/auth/v1/authorize`);
|
|
38
|
+
u.searchParams.set('provider', provider);
|
|
39
|
+
u.searchParams.set('redirect_to', redirectTo);
|
|
40
|
+
u.searchParams.set('code_challenge', codeChallenge);
|
|
41
|
+
u.searchParams.set('code_challenge_method', 's256');
|
|
42
|
+
return u.toString();
|
|
43
|
+
}
|
|
44
|
+
/** Exchange the PKCE auth code + verifier for a Supabase session. */
|
|
45
|
+
async exchangeCode(code, verifier) {
|
|
46
|
+
const res = await axios.post(`${this.url}/auth/v1/token?grant_type=pkce`, { auth_code: code, code_verifier: verifier }, {
|
|
47
|
+
headers: { apikey: this.anonKey, 'Content-Type': 'application/json' },
|
|
48
|
+
timeout: 15_000,
|
|
49
|
+
});
|
|
50
|
+
const at = res.data?.access_token;
|
|
51
|
+
const rt = res.data?.refresh_token;
|
|
52
|
+
if (typeof at !== 'string' || typeof rt !== 'string') {
|
|
53
|
+
throw new Error('Supabase did not return a session');
|
|
54
|
+
}
|
|
55
|
+
return { access_token: at, refresh_token: rt };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=social.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/auth/social.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/stores.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OAuthClientInformationFull } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
2
|
+
import type { SupabaseSession } from './api-auth.js';
|
|
2
3
|
/**
|
|
3
4
|
* Registered-clients store for Dynamic Client Registration, optionally backed
|
|
4
5
|
* by a JSON file so registrations survive container restarts and redeploys.
|
|
@@ -27,7 +28,8 @@ export declare class InMemoryClientsStore {
|
|
|
27
28
|
private persist;
|
|
28
29
|
}
|
|
29
30
|
export interface AuthCodeRecord {
|
|
30
|
-
|
|
31
|
+
/** Supabase session captured at login, exchanged for our tokens at /token. */
|
|
32
|
+
session: SupabaseSession;
|
|
31
33
|
orgId: number;
|
|
32
34
|
codeChallenge: string;
|
|
33
35
|
redirectUri: string;
|
package/dist/auth/stores.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/auth/stores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/auth/stores.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/stores.test.js
CHANGED
|
@@ -18,7 +18,7 @@ describe('InMemoryClientsStore', () => {
|
|
|
18
18
|
});
|
|
19
19
|
describe('AuthCodeStore', () => {
|
|
20
20
|
const rec = {
|
|
21
|
-
|
|
21
|
+
session: { access_token: 'AT', refresh_token: 'RT' },
|
|
22
22
|
orgId: 7,
|
|
23
23
|
codeChallenge: 'chal',
|
|
24
24
|
redirectUri: 'https://claude.ai/cb',
|
|
@@ -29,7 +29,7 @@ describe('AuthCodeStore', () => {
|
|
|
29
29
|
const code = store.create(rec);
|
|
30
30
|
expect(typeof code).toBe('string');
|
|
31
31
|
const first = store.take(code);
|
|
32
|
-
expect(first?.
|
|
32
|
+
expect(first?.session.access_token).toBe('AT');
|
|
33
33
|
expect(store.take(code)).toBeUndefined(); // one-time
|
|
34
34
|
});
|
|
35
35
|
it('does not return an expired code', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stores.test.js","sourceRoot":"","sources":["../../src/auth/stores.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC;YACrC,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,CAAC,4BAA4B,CAAC;SACvC,CAAC,CAAC;QACV,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,GAAG,GAAG;QACV,
|
|
1
|
+
{"version":3,"file":"stores.test.js","sourceRoot":"","sources":["../../src/auth/stores.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC;YACrC,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,CAAC,4BAA4B,CAAC;SACvC,CAAC,CAAC;QACV,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,GAAG,GAAG;QACV,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;QACpD,KAAK,EAAE,CAAC;QACR,aAAa,EAAE,MAAM;QACrB,WAAW,EAAE,sBAAsB;QACnC,QAAQ,EAAE,IAAI;KACf,CAAC;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,WAAW;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB;QACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
export interface TokenPayload {
|
|
2
|
-
apiKey: string;
|
|
3
2
|
orgId: number;
|
|
4
3
|
type: 'access' | 'refresh';
|
|
5
4
|
exp: number;
|
|
6
5
|
jti: string;
|
|
6
|
+
/**
|
|
7
|
+
* Exactly one identity is carried, depending on the login method:
|
|
8
|
+
* - `apiKey` — legacy BYO-key OAuth tokens (still honoured until expiry).
|
|
9
|
+
* - `sbAccess` — Supabase access JWT, embedded in OUR access tokens. Its own
|
|
10
|
+
* expiry always sits AFTER ours (see provider.mintSessionTokens), so it is
|
|
11
|
+
* guaranteed valid for the whole life of our access token — no mid-request
|
|
12
|
+
* refresh, no server-side session state.
|
|
13
|
+
* - `sbRefresh` — Supabase (rotating) refresh token, embedded in OUR refresh
|
|
14
|
+
* tokens; spent once per refresh to mint the next session.
|
|
15
|
+
*/
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
sbAccess?: string;
|
|
18
|
+
sbRefresh?: string;
|
|
7
19
|
}
|
|
20
|
+
/** Decode a JWT's `exp` (epoch seconds) without verifying the signature. */
|
|
21
|
+
export declare function jwtExp(token: string): number | null;
|
|
8
22
|
export declare class TokenError extends Error {
|
|
9
23
|
}
|
|
10
24
|
export interface TokenCodec {
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
2
|
+
/** Decode a JWT's `exp` (epoch seconds) without verifying the signature. */
|
|
3
|
+
export function jwtExp(token) {
|
|
4
|
+
const parts = token.split('.');
|
|
5
|
+
if (parts.length !== 3)
|
|
6
|
+
return null;
|
|
7
|
+
try {
|
|
8
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
|
|
9
|
+
return typeof payload.exp === 'number' ? payload.exp : null;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
2
15
|
export class TokenError extends Error {
|
|
3
16
|
}
|
|
4
17
|
const IV_LEN = 12;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-crypto.js","sourceRoot":"","sources":["../../src/auth/token-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"token-crypto.js","sourceRoot":"","sources":["../../src/auth/token-crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
export interface Config {
|
|
2
|
-
|
|
2
|
+
/** Raw `r2b_` API key (X-API-Key). Used by stdio mode and the legacy path. */
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Supabase access JWT (Authorization: Bearer). Used by the HTTP OAuth path
|
|
6
|
+
* after a user logs in with their rent2b account. Mutually exclusive with
|
|
7
|
+
* `apiKey`; when set, requests authenticate as the user (RLS applies).
|
|
8
|
+
*/
|
|
9
|
+
accessToken?: string;
|
|
3
10
|
apiUrl: string;
|
|
4
11
|
/**
|
|
5
|
-
* Pre-resolved organization id
|
|
6
|
-
*
|
|
7
|
-
*
|
|
12
|
+
* Pre-resolved organization id. When provided, the client skips the org
|
|
13
|
+
* lookup — used in HTTP mode where the auth layer already resolved the org
|
|
14
|
+
* and set it on req.auth.
|
|
8
15
|
*/
|
|
9
16
|
organizationId?: number;
|
|
10
17
|
}
|
|
11
18
|
export declare function loadConfig(): Config;
|
|
12
|
-
export
|
|
19
|
+
export interface HttpConfig {
|
|
13
20
|
apiUrl: string;
|
|
14
|
-
|
|
21
|
+
/** Supabase URL + anon key enable server-side social login (Google/Apple). */
|
|
22
|
+
supabaseUrl?: string;
|
|
23
|
+
supabaseAnonKey?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function loadHttpConfig(): HttpConfig;
|
|
15
26
|
export declare function validateApiKey(apiKey: string): void;
|
|
16
27
|
export declare function extractApiKey(headers: Record<string, string | string[] | undefined>): string;
|
package/dist/config.js
CHANGED
|
@@ -13,6 +13,8 @@ export function loadConfig() {
|
|
|
13
13
|
export function loadHttpConfig() {
|
|
14
14
|
return {
|
|
15
15
|
apiUrl: process.env.RENT2B_API_URL || DEFAULT_API_URL,
|
|
16
|
+
supabaseUrl: process.env.SUPABASE_URL,
|
|
17
|
+
supabaseAnonKey: process.env.SUPABASE_ANON_KEY,
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
export function validateApiKey(apiKey) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,MAAM,eAAe,GAAG,6CAA6C,CAAC;AAEtE,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO;QACL,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,eAAe;KACtD,CAAC;AACJ,CAAC;AASD,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,eAAe;QACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAsD;IAClF,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAuB,CAAC;IAClE,IAAI,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAuB,CAAC;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;AACnG,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ import { createTokenCodec } from './auth/token-crypto.js';
|
|
|
8
8
|
import { InMemoryClientsStore, AuthCodeStore } from './auth/stores.js';
|
|
9
9
|
import { Rent2bOAuthProvider } from './auth/provider.js';
|
|
10
10
|
import { registerOAuth, xApiKeyToBearer } from './auth/http-oauth.js';
|
|
11
|
+
import { ApiAuthClient } from './auth/api-auth.js';
|
|
12
|
+
import { SupabaseOAuthClient, SocialFlowStore } from './auth/social.js';
|
|
11
13
|
async function main() {
|
|
12
14
|
const args = process.argv.slice(2);
|
|
13
15
|
const useSSE = args.includes('--sse');
|
|
@@ -30,10 +32,13 @@ async function main() {
|
|
|
30
32
|
app.get('/health', (_req, res) => {
|
|
31
33
|
res.json({ status: 'ok' });
|
|
32
34
|
});
|
|
33
|
-
// OAuth 2.1 + Dynamic Client Registration. The "login" is the user
|
|
34
|
-
//
|
|
35
|
-
//
|
|
35
|
+
// OAuth 2.1 + Dynamic Client Registration. The "login" is the user signing
|
|
36
|
+
// in with their rent2b account (email/password or Google/Apple, delegated
|
|
37
|
+
// to the rent2b-api auth endpoints); the issued token carries the resulting
|
|
38
|
+
// Supabase session. Raw r2b_ bearer tokens (and X-API-Key via the shim)
|
|
39
|
+
// keep working unchanged.
|
|
36
40
|
const oauthCfg = loadOAuthConfig();
|
|
41
|
+
const apiAuth = new ApiAuthClient(httpConfig.apiUrl);
|
|
37
42
|
const validateKey = async (apiKey) => {
|
|
38
43
|
validateApiKey(apiKey);
|
|
39
44
|
const client = new Rent2bApiClient({ apiKey, apiUrl: httpConfig.apiUrl });
|
|
@@ -45,13 +50,24 @@ async function main() {
|
|
|
45
50
|
// their 1h access token expired. Mount a volume at /data on the gateway;
|
|
46
51
|
// if it's absent the store silently falls back to memory.
|
|
47
52
|
const clientsPath = process.env.OAUTH_CLIENTS_PATH || '/data/oauth-clients.json';
|
|
53
|
+
// Social login (Google/Apple): the MCP runs the Supabase PKCE flow itself
|
|
54
|
+
// (server-side code exchange), enabled when SUPABASE_URL + SUPABASE_ANON_KEY
|
|
55
|
+
// are configured. Email/password works regardless.
|
|
56
|
+
const social = httpConfig.supabaseUrl && httpConfig.supabaseAnonKey
|
|
57
|
+
? {
|
|
58
|
+
oauth: new SupabaseOAuthClient(httpConfig.supabaseUrl, httpConfig.supabaseAnonKey),
|
|
59
|
+
store: new SocialFlowStore(),
|
|
60
|
+
}
|
|
61
|
+
: undefined;
|
|
48
62
|
const provider = new Rent2bOAuthProvider({
|
|
49
63
|
codec: createTokenCodec(oauthCfg.encryptionKey),
|
|
50
64
|
clientsStore: new InMemoryClientsStore(clientsPath),
|
|
51
65
|
codeStore: new AuthCodeStore(),
|
|
66
|
+
apiAuth,
|
|
52
67
|
validateKey,
|
|
68
|
+
socialLogin: !!social,
|
|
53
69
|
});
|
|
54
|
-
const bearer = registerOAuth(app, { oauthCfg, provider,
|
|
70
|
+
const bearer = registerOAuth(app, { oauthCfg, provider, apiAuth, social });
|
|
55
71
|
// Stateless Streamable HTTP: a fresh MCP server + transport per request, with
|
|
56
72
|
// NO server-side session affinity. tools/list and tool calls work on any
|
|
57
73
|
// request without a prior session, so the client can refresh the tool list
|
|
@@ -60,17 +76,20 @@ async function main() {
|
|
|
60
76
|
// the previous stateful mode left clients stuck on a dead session after a
|
|
61
77
|
// restart, requiring a manual reconnect.)
|
|
62
78
|
app.post('/mcp', xApiKeyToBearer, bearer, async (req, res) => {
|
|
63
|
-
// The bearer auth layer (verifyAccessToken) already resolved
|
|
64
|
-
//
|
|
65
|
-
//
|
|
79
|
+
// The bearer auth layer (verifyAccessToken) already resolved the caller's
|
|
80
|
+
// credential and organization. The credential is either a Supabase access
|
|
81
|
+
// token (user logged in via OAuth) or a raw r2b_ key (legacy/direct);
|
|
82
|
+
// reuse the org instead of looking it up again.
|
|
66
83
|
const apiKey = req.auth?.extra?.apiKey;
|
|
84
|
+
const accessToken = req.auth?.extra?.supabaseAccessToken;
|
|
67
85
|
const organizationId = req.auth?.extra?.orgId;
|
|
68
|
-
if (!apiKey) {
|
|
69
|
-
res.status(401).json({ error: 'No
|
|
86
|
+
if (!apiKey && !accessToken) {
|
|
87
|
+
res.status(401).json({ error: 'No credential associated with token' });
|
|
70
88
|
return;
|
|
71
89
|
}
|
|
72
90
|
const apiClient = new Rent2bApiClient({
|
|
73
91
|
apiKey,
|
|
92
|
+
accessToken,
|
|
74
93
|
apiUrl: httpConfig.apiUrl,
|
|
75
94
|
organizationId,
|
|
76
95
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|