@honeyfield/rent2b-mcp 1.2.0 → 1.2.2
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 +14 -5
- package/dist/api-client.js.map +1 -1
- package/dist/api-client.test.d.ts +1 -0
- package/dist/api-client.test.js +41 -0
- package/dist/api-client.test.js.map +1 -0
- package/dist/auth/authorize-page.d.ts +18 -0
- package/dist/auth/authorize-page.js +60 -0
- package/dist/auth/authorize-page.js.map +1 -0
- package/dist/auth/authorize-page.test.d.ts +1 -0
- package/dist/auth/authorize-page.test.js +37 -0
- package/dist/auth/authorize-page.test.js.map +1 -0
- package/dist/auth/http-oauth.d.ts +28 -0
- package/dist/auth/http-oauth.js +93 -0
- package/dist/auth/http-oauth.js.map +1 -0
- package/dist/auth/oauth-config.d.ts +6 -0
- package/dist/auth/oauth-config.js +16 -0
- package/dist/auth/oauth-config.js.map +1 -0
- package/dist/auth/oauth-config.test.d.ts +1 -0
- package/dist/auth/oauth-config.test.js +25 -0
- package/dist/auth/oauth-config.test.js.map +1 -0
- package/dist/auth/provider.d.ts +28 -0
- package/dist/auth/provider.js +127 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/provider.test.d.ts +1 -0
- package/dist/auth/provider.test.js +80 -0
- package/dist/auth/provider.test.js.map +1 -0
- package/dist/auth/stores.d.ts +41 -0
- package/dist/auth/stores.js +82 -0
- package/dist/auth/stores.js.map +1 -0
- package/dist/auth/stores.test.d.ts +1 -0
- package/dist/auth/stores.test.js +41 -0
- package/dist/auth/stores.test.js.map +1 -0
- package/dist/auth/token-crypto.d.ts +14 -0
- package/dist/auth/token-crypto.js +50 -0
- package/dist/auth/token-crypto.js.map +1 -0
- package/dist/auth/token-crypto.test.d.ts +1 -0
- package/dist/auth/token-crypto.test.js +40 -0
- package/dist/auth/token-crypto.test.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js.map +1 -1
- package/dist/generator/openapi-parser.js +21 -0
- package/dist/generator/openapi-parser.js.map +1 -1
- package/dist/generator/tool-generator.js +19 -1
- package/dist/generator/tool-generator.js.map +1 -1
- package/dist/generator/tool-generator.test.d.ts +1 -0
- package/dist/generator/tool-generator.test.js +35 -0
- package/dist/generator/tool-generator.test.js.map +1 -0
- package/dist/index.js +91 -60
- package/dist/index.js.map +1 -1
- package/dist/overrides/tool-overrides.json +60 -0
- package/generated/tools.json +1395 -215
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { randomUUID } from 'crypto';
|
|
3
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
3
|
import { loadConfig, loadHttpConfig, extractApiKey, validateApiKey } from './config.js';
|
|
5
4
|
import { Rent2bApiClient } from './api-client.js';
|
|
6
5
|
import { createServer } from './server.js';
|
|
6
|
+
import { loadOAuthConfig } from './auth/oauth-config.js';
|
|
7
|
+
import { createTokenCodec } from './auth/token-crypto.js';
|
|
8
|
+
import { InMemoryClientsStore, AuthCodeStore } from './auth/stores.js';
|
|
9
|
+
import { Rent2bOAuthProvider } from './auth/provider.js';
|
|
10
|
+
import { registerOAuth, xApiKeyToBearer } from './auth/http-oauth.js';
|
|
7
11
|
async function main() {
|
|
8
12
|
const args = process.argv.slice(2);
|
|
9
13
|
const useSSE = args.includes('--sse');
|
|
@@ -14,76 +18,103 @@ async function main() {
|
|
|
14
18
|
const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
15
19
|
const express = (await import('express')).default;
|
|
16
20
|
const app = express();
|
|
21
|
+
// Behind the Caddy gateway every request carries X-Forwarded-For. Trust
|
|
22
|
+
// exactly ONE proxy hop (Caddy) so Express reads the real client IP. Do NOT
|
|
23
|
+
// use `true`: a permissive trust-proxy makes express-rate-limit throw
|
|
24
|
+
// ERR_ERL_PERMISSIVE_TRUST_PROXY on every OAuth request (the limiter can no
|
|
25
|
+
// longer derive a trustworthy client IP, so IP rate-limiting is silently
|
|
26
|
+
// bypassable). `1` = trust the first hop only, which satisfies the limiter
|
|
27
|
+
// and still resolves the correct client IP for a single reverse proxy.
|
|
28
|
+
app.set('trust proxy', 1);
|
|
17
29
|
app.use(express.json());
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
app.get('/health', (_req, res) => {
|
|
31
|
+
res.json({ status: 'ok' });
|
|
32
|
+
});
|
|
33
|
+
// OAuth 2.1 + Dynamic Client Registration. The "login" is the user entering
|
|
34
|
+
// their own r2b_ API key; the issued token is bound to that key. Raw r2b_
|
|
35
|
+
// bearer tokens (and X-API-Key via the shim) keep working unchanged.
|
|
36
|
+
const oauthCfg = loadOAuthConfig();
|
|
37
|
+
const validateKey = async (apiKey) => {
|
|
38
|
+
validateApiKey(apiKey);
|
|
39
|
+
const client = new Rent2bApiClient({ apiKey, apiUrl: httpConfig.apiUrl });
|
|
40
|
+
return client.resolveOrganization();
|
|
41
|
+
};
|
|
42
|
+
// Persist DCR client registrations so they survive restarts/redeploys.
|
|
43
|
+
// Without this, every restart wiped the in-memory map and existing Claude
|
|
44
|
+
// connectors failed their refresh-token exchange (`invalid_client`) once
|
|
45
|
+
// their 1h access token expired. Mount a volume at /data on the gateway;
|
|
46
|
+
// if it's absent the store silently falls back to memory.
|
|
47
|
+
const clientsPath = process.env.OAUTH_CLIENTS_PATH || '/data/oauth-clients.json';
|
|
48
|
+
const provider = new Rent2bOAuthProvider({
|
|
49
|
+
codec: createTokenCodec(oauthCfg.encryptionKey),
|
|
50
|
+
clientsStore: new InMemoryClientsStore(clientsPath),
|
|
51
|
+
codeStore: new AuthCodeStore(),
|
|
52
|
+
validateKey,
|
|
53
|
+
});
|
|
54
|
+
const bearer = registerOAuth(app, { oauthCfg, provider, validateKey });
|
|
55
|
+
// Stateless Streamable HTTP: a fresh MCP server + transport per request, with
|
|
56
|
+
// NO server-side session affinity. tools/list and tool calls work on any
|
|
57
|
+
// request without a prior session, so the client can refresh the tool list
|
|
58
|
+
// at any time — including immediately after a redeploy/restart, since there
|
|
59
|
+
// is no in-memory session to lose. (Matches the FastMCP stateless behaviour;
|
|
60
|
+
// the previous stateful mode left clients stuck on a dead session after a
|
|
61
|
+
// restart, requiring a manual reconnect.)
|
|
62
|
+
app.post('/mcp', xApiKeyToBearer, bearer, async (req, res) => {
|
|
63
|
+
// The bearer auth layer (verifyAccessToken) already resolved both of these:
|
|
64
|
+
// the api key, and the organization it belongs to (from the OAuth token, or
|
|
65
|
+
// via /zapier/me for a raw key). Reuse the org instead of looking it up again.
|
|
66
|
+
const apiKey = req.auth?.extra?.apiKey;
|
|
67
|
+
const organizationId = req.auth?.extra?.orgId;
|
|
68
|
+
if (!apiKey) {
|
|
69
|
+
res.status(401).json({ error: 'No API key associated with token' });
|
|
35
70
|
return;
|
|
36
71
|
}
|
|
37
|
-
const apiClient = new Rent2bApiClient({
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
const apiClient = new Rent2bApiClient({
|
|
73
|
+
apiKey,
|
|
74
|
+
apiUrl: httpConfig.apiUrl,
|
|
75
|
+
organizationId,
|
|
76
|
+
});
|
|
77
|
+
// Defensive fallback: if the auth layer didn't supply an org, resolve it now.
|
|
78
|
+
if (organizationId == null) {
|
|
79
|
+
try {
|
|
80
|
+
await apiClient.resolveOrganization();
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const message = err instanceof Error
|
|
84
|
+
? err.message
|
|
85
|
+
: typeof err === 'object' && err !== null && 'message' in err
|
|
86
|
+
? String(err.message)
|
|
87
|
+
: String(err);
|
|
88
|
+
res.status(401).json({ error: `Invalid API key: ${message}` });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
49
91
|
}
|
|
92
|
+
const server = createServer(apiClient);
|
|
50
93
|
const transport = new StreamableHTTPServerTransport({
|
|
51
|
-
sessionIdGenerator:
|
|
94
|
+
sessionIdGenerator: undefined, // stateless — no session tracking
|
|
52
95
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const sid = transport.sessionId;
|
|
56
|
-
if (sid)
|
|
57
|
-
sessions.delete(sid);
|
|
96
|
+
res.on('close', () => {
|
|
97
|
+
transport.close();
|
|
58
98
|
server.close();
|
|
59
|
-
};
|
|
99
|
+
});
|
|
60
100
|
await server.connect(transport);
|
|
61
|
-
|
|
62
|
-
sessions.set(transport.sessionId, { transport, apiClient });
|
|
63
|
-
}
|
|
64
|
-
await transport.handleRequest(req, res);
|
|
65
|
-
});
|
|
66
|
-
app.get('/mcp', async (req, res) => {
|
|
67
|
-
const sessionId = req.headers['mcp-session-id'];
|
|
68
|
-
if (!sessionId || !sessions.has(sessionId)) {
|
|
69
|
-
res.status(400).json({ error: 'Invalid or missing session ID' });
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const session = sessions.get(sessionId);
|
|
73
|
-
await session.transport.handleRequest(req, res);
|
|
74
|
-
});
|
|
75
|
-
app.delete('/mcp', async (req, res) => {
|
|
76
|
-
const sessionId = req.headers['mcp-session-id'];
|
|
77
|
-
if (!sessionId || !sessions.has(sessionId)) {
|
|
78
|
-
res.status(400).json({ error: 'Invalid or missing session ID' });
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const session = sessions.get(sessionId);
|
|
82
|
-
await session.transport.handleRequest(req, res);
|
|
101
|
+
await transport.handleRequest(req, res, req.body);
|
|
83
102
|
});
|
|
103
|
+
// Stateless mode has no standalone SSE notification stream or session
|
|
104
|
+
// teardown, so GET/DELETE on /mcp are not supported.
|
|
105
|
+
const methodNotAllowed = (_req, res) => {
|
|
106
|
+
res.status(405).json({
|
|
107
|
+
jsonrpc: '2.0',
|
|
108
|
+
error: { code: -32000, message: 'Method Not Allowed (stateless server)' },
|
|
109
|
+
id: null,
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
app.get('/mcp', methodNotAllowed);
|
|
113
|
+
app.delete('/mcp', methodNotAllowed);
|
|
84
114
|
app.listen(port, () => {
|
|
85
115
|
console.error(`rent2b MCP server (Streamable HTTP) listening on port ${port}`);
|
|
86
|
-
console.error(
|
|
116
|
+
console.error(`OAuth issuer: ${oauthCfg.issuerUrl.href}`);
|
|
117
|
+
console.error('Auth: OAuth2.1 (BYO r2b_ key) or direct Authorization/X-API-Key header');
|
|
87
118
|
});
|
|
88
119
|
}
|
|
89
120
|
else if (useSSE) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,
|
|
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;AAOtE,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,QAAQ,CACnB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,EAClE,EAAE,CACH,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;QAEpC,MAAM,EAAE,6BAA6B,EAAE,GAAG,MAAM,MAAM,CACpD,oDAAoD,CACrD,CAAC;QACF,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,wEAAwE;QACxE,4EAA4E;QAC5E,sEAAsE;QACtE,4EAA4E;QAC5E,yEAAyE;QACzE,2EAA2E;QAC3E,uEAAuE;QACvE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QAC1B,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAExB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,4EAA4E;QAC5E,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;QACnC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAc,EAAmB,EAAE;YAC5D,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YAC1E,OAAO,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACtC,CAAC,CAAC;QACF,uEAAuE;QACvE,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,0DAA0D;QAC1D,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,0BAA0B,CAAC;QAC/D,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC;YACvC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC/C,YAAY,EAAE,IAAI,oBAAoB,CAAC,WAAW,CAAC;YACnD,SAAS,EAAE,IAAI,aAAa,EAAE;YAC9B,WAAW;SACZ,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;QAEvE,8EAA8E;QAC9E,yEAAyE;QACzE,2EAA2E;QAC3E,4EAA4E;QAC5E,6EAA6E;QAC7E,0EAA0E;QAC1E,0CAA0C;QAC1C,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3D,4EAA4E;YAC5E,4EAA4E;YAC5E,+EAA+E;YAC/E,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,MAA4B,CAAC;YAC7D,MAAM,cAAc,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAA2B,CAAC;YACpE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;gBACpE,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC;gBACpC,MAAM;gBACN,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,cAAc;aACf,CAAC,CAAC;YACH,8EAA8E;YAC9E,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,mBAAmB,EAAE,CAAC;gBACxC,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK;wBAClC,CAAC,CAAC,GAAG,CAAC,OAAO;wBACb,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;4BAC3D,CAAC,CAAC,MAAM,CAAE,GAA4B,CAAC,OAAO,CAAC;4BAC/C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC/D,OAAO;gBACT,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;gBAClD,kBAAkB,EAAE,SAAS,EAAE,kCAAkC;aAClE,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACnB,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClB,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC,CAAC,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,sEAAsE;QACtE,qDAAqD;QACrD,MAAM,gBAAgB,GAAG,CACvB,IAA+B,EAC/B,GAA+B,EACzB,EAAE;YACR,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uCAAuC,EAAE;gBACzE,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;QACL,CAAC,CAAC;QACF,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAClC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAErC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACpB,OAAO,CAAC,KAAK,CAAC,yDAAyD,IAAI,EAAE,CAAC,CAAC;YAC/E,OAAO,CAAC,KAAK,CAAC,iBAAiB,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,MAAM,EAAE,CAAC;QAClB,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;QAEpC,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CACzC,yCAAyC,CAC1C,CAAC;QACF,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QAEtB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;QAEpD,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACjC,IAAI,MAAc,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACpC,cAAc,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YAE7E,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,mBAAmB,EAAE,CAAC;YACxC,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK;oBAClC,CAAC,CAAC,GAAG,CAAC,OAAO;oBACb,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;wBAC3D,CAAC,CAAC,MAAM,CAAE,GAA4B,CAAC,OAAO,CAAC;wBAC/C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC3D,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAE5D,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACnB,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,SAAmB,CAAC;YAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxC,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,OAAO,CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACpB,OAAO,CAAC,KAAK,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;YACnE,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,0CAA0C;QAC1C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAE9C,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,mBAAmB,EAAE,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GACX,GAAG,YAAY,KAAK;gBAClB,CAAC,CAAC,GAAG,CAAC,OAAO;gBACb,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;oBAC3D,CAAC,CAAC,MAAM,CAAE,GAA4B,CAAC,OAAO,CAAC;oBAC/C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -179,6 +179,66 @@
|
|
|
179
179
|
"GET /statistics/organization/{organizationId}/utilization": {
|
|
180
180
|
"name": "rent2b_statistics_utilization",
|
|
181
181
|
"description": "Get utilization statistics for the organization."
|
|
182
|
+
},
|
|
183
|
+
"GET /organizations/{organizationId}/website-content": {
|
|
184
|
+
"name": "rent2b_website_content_get",
|
|
185
|
+
"description": "Get the public booking page content (texts/sections) for the organization."
|
|
186
|
+
},
|
|
187
|
+
"PUT /organizations/{organizationId}/website-content": {
|
|
188
|
+
"name": "rent2b_website_content_update",
|
|
189
|
+
"description": "Update the public booking page content (texts/sections) for the organization."
|
|
190
|
+
},
|
|
191
|
+
"GET /organizations/{organizationId}/branding": {
|
|
192
|
+
"name": "rent2b_branding_get",
|
|
193
|
+
"description": "Get the organization branding (colors, text). Logo/background are images set separately."
|
|
194
|
+
},
|
|
195
|
+
"PUT /organizations/{organizationId}/branding": {
|
|
196
|
+
"name": "rent2b_branding_update",
|
|
197
|
+
"description": "Update the organization branding (colors, text)."
|
|
198
|
+
},
|
|
199
|
+
"GET /settings": {
|
|
200
|
+
"name": "rent2b_settings_get",
|
|
201
|
+
"description": "Get organization and user settings."
|
|
202
|
+
},
|
|
203
|
+
"PUT /settings/organization": {
|
|
204
|
+
"name": "rent2b_settings_organization_update",
|
|
205
|
+
"description": "Update organization settings."
|
|
206
|
+
},
|
|
207
|
+
"PUT /settings/user": {
|
|
208
|
+
"name": "rent2b_settings_user_update",
|
|
209
|
+
"description": "Update the current user settings."
|
|
210
|
+
},
|
|
211
|
+
"GET /profile": {
|
|
212
|
+
"name": "rent2b_profile_get",
|
|
213
|
+
"description": "Get the current owner profile."
|
|
214
|
+
},
|
|
215
|
+
"PUT /profile": {
|
|
216
|
+
"name": "rent2b_profile_update",
|
|
217
|
+
"description": "Update the current owner profile."
|
|
218
|
+
},
|
|
219
|
+
"GET /campaign-links": {
|
|
220
|
+
"name": "rent2b_campaign_links_list",
|
|
221
|
+
"description": "List campaign tracking links for the booking page."
|
|
222
|
+
},
|
|
223
|
+
"GET /campaign-links/{id}": {
|
|
224
|
+
"name": "rent2b_campaign_links_get",
|
|
225
|
+
"description": "Get a campaign link by ID."
|
|
226
|
+
},
|
|
227
|
+
"POST /campaign-links": {
|
|
228
|
+
"name": "rent2b_campaign_links_create",
|
|
229
|
+
"description": "Create a campaign tracking link."
|
|
230
|
+
},
|
|
231
|
+
"PATCH /campaign-links/{id}": {
|
|
232
|
+
"name": "rent2b_campaign_links_update",
|
|
233
|
+
"description": "Update a campaign link."
|
|
234
|
+
},
|
|
235
|
+
"DELETE /campaign-links/{id}": {
|
|
236
|
+
"name": "rent2b_campaign_links_delete",
|
|
237
|
+
"description": "Delete a campaign link."
|
|
238
|
+
},
|
|
239
|
+
"GET /campaign-links/{id}/analytics": {
|
|
240
|
+
"name": "rent2b_campaign_links_analytics",
|
|
241
|
+
"description": "Get analytics (clicks, conversions) for a campaign link."
|
|
182
242
|
}
|
|
183
243
|
}
|
|
184
244
|
}
|