@datasynx/agentic-crm 1.6.0 → 1.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.
- package/dist/cli.js +39 -70
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +24 -1
- package/dist/daemon/worker.js.map +1 -1
- package/dist/{imap-o6PRuBvm.js → imap-BRgNh3T3.js} +2 -2
- package/dist/{imap-o6PRuBvm.js.map → imap-BRgNh3T3.js.map} +1 -1
- package/dist/imap-DzeqMdZ3.js +2 -0
- package/dist/{index-BBAlKZg6.d.ts → index-DoYT-azq.d.ts} +8 -8
- package/dist/index-DoYT-azq.d.ts.map +1 -0
- package/dist/{index-DNHsURo5.d.cts → index-Ewy4f1XW.d.cts} +12 -12
- package/dist/{index-DNHsURo5.d.cts.map → index-Ewy4f1XW.d.cts.map} +1 -1
- package/dist/index.d.cts +12 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/{knowledge-base-Cc0niBFf.js → knowledge-base-Byo0zwM5.js} +2 -1
- package/dist/knowledge-base-Byo0zwM5.js.map +1 -0
- package/dist/{login-CYgla6-A.js → login-yt9OOQQk.js} +3 -2
- package/dist/{login-CYgla6-A.js.map → login-yt9OOQQk.js.map} +1 -1
- package/dist/mailbox-config-Bu-J1O4I.js +2 -0
- package/dist/mailbox-config-Dn2xTn9N.js +67 -0
- package/dist/mailbox-config-Dn2xTn9N.js.map +1 -0
- package/dist/mailbox-poll-B8dvFAXT.js +80 -0
- package/dist/mailbox-poll-B8dvFAXT.js.map +1 -0
- package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
- package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
- package/dist/mcp.cjs +303 -137
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +303 -137
- package/dist/mcp.js.map +1 -1
- package/dist/{microsoft-DgbVlHdT.js → microsoft-dsC1fQQG.js} +2 -38
- package/dist/microsoft-dsC1fQQG.js.map +1 -0
- package/dist/{server-BbInMUgp.js → server-C0XkJQBo.js} +167 -132
- package/dist/server-C0XkJQBo.js.map +1 -0
- package/dist/{token-resolver-BRLOmRvF.js → token-resolver-D98qPOOf.js} +3 -2
- package/dist/{token-resolver-BRLOmRvF.js.map → token-resolver-D98qPOOf.js.map} +1 -1
- package/dist/token-store-B0h0USqe.js +43 -0
- package/dist/token-store-B0h0USqe.js.map +1 -0
- package/dist/token-store-CEmz8d-0.js +2 -0
- package/dist/velocity-BtX1l5Gh.js +2 -0
- package/dist/velocity-C2l4cW0K.js +123 -0
- package/dist/velocity-C2l4cW0K.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-BBAlKZg6.d.ts.map +0 -1
- package/dist/knowledge-base-Cc0niBFf.js.map +0 -1
- package/dist/microsoft-DgbVlHdT.js.map +0 -1
- package/dist/server-BbInMUgp.js.map +0 -1
|
@@ -1,40 +1,4 @@
|
|
|
1
|
-
import { t as writeFileAtomic } from "./atomic-write-8yjqqLtS.js";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import fs from "fs";
|
|
4
1
|
import { OAuth2Client } from "google-auth-library";
|
|
5
|
-
//#region src/sync/oauth/token-store.ts
|
|
6
|
-
function tokensPath(dataDir) {
|
|
7
|
-
return path.join(dataDir, ".agentic", "mailbox-tokens.json");
|
|
8
|
-
}
|
|
9
|
-
function keyOf(provider, user) {
|
|
10
|
-
return `${provider}:${user.toLowerCase()}`;
|
|
11
|
-
}
|
|
12
|
-
function readAll(dataDir) {
|
|
13
|
-
const file = tokensPath(dataDir);
|
|
14
|
-
if (!fs.existsSync(file)) return {};
|
|
15
|
-
try {
|
|
16
|
-
return JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
17
|
-
} catch {
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/** Persist (upsert) a mailbox OAuth token. */
|
|
22
|
-
function saveMailboxToken(dataDir, token) {
|
|
23
|
-
const all = readAll(dataDir);
|
|
24
|
-
all[keyOf(token.provider, token.user)] = token;
|
|
25
|
-
const file = tokensPath(dataDir);
|
|
26
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
27
|
-
writeFileAtomic(file, JSON.stringify(all, null, 2));
|
|
28
|
-
}
|
|
29
|
-
/** Load a stored token for a provider+user, or undefined. */
|
|
30
|
-
function loadMailboxToken(dataDir, provider, user) {
|
|
31
|
-
return readAll(dataDir)[keyOf(provider, user)];
|
|
32
|
-
}
|
|
33
|
-
/** True when the access token is missing or expires within `skewMs` (default 60s). */
|
|
34
|
-
function isTokenExpired(token, skewMs = 6e4, now = Date.now()) {
|
|
35
|
-
return !token.accessToken || token.expiresAt <= now + skewMs;
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
2
|
//#region src/sync/oauth/google.ts
|
|
39
3
|
const GMAIL_IMAP_SCOPE = "https://mail.google.com/";
|
|
40
4
|
/** Loopback redirect for the desktop/installed-app flow. */
|
|
@@ -154,6 +118,6 @@ function describe(e) {
|
|
|
154
118
|
return e.error_description ? ` (${e.error_description.split("\n")[0]})` : "";
|
|
155
119
|
}
|
|
156
120
|
//#endregion
|
|
157
|
-
export { buildAuthUrl as a, refreshGoogleToken as c,
|
|
121
|
+
export { buildAuthUrl as a, refreshGoogleToken as c, DEFAULT_REDIRECT as i, refreshMicrosoftToken as n, createOAuthClient as o, requestDeviceCode as r, exchangeCodeForTokens as s, pollForToken as t };
|
|
158
122
|
|
|
159
|
-
//# sourceMappingURL=microsoft-
|
|
123
|
+
//# sourceMappingURL=microsoft-dsC1fQQG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microsoft-dsC1fQQG.js","names":[],"sources":["../src/sync/oauth/google.ts","../src/sync/oauth/microsoft.ts"],"sourcesContent":["// src/sync/oauth/google.ts\n//\n// Google OAuth2 for Gmail IMAP (XOAUTH2). IMAP requires the FULL mail scope\n// `https://mail.google.com/` — the gmail.readonly scope does NOT grant IMAP.\nimport { OAuth2Client } from \"google-auth-library\";\n\nexport const GMAIL_IMAP_SCOPE = \"https://mail.google.com/\";\n/** Loopback redirect for the desktop/installed-app flow. */\nexport const DEFAULT_REDIRECT = \"http://127.0.0.1\";\n\nexport interface GoogleTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n}\n\n/** Minimal slice of OAuth2Client we use (lets tests inject a fake). */\nexport interface GoogleOAuthClient {\n generateAuthUrl(opts: {\n access_type?: string;\n scope?: string | string[];\n prompt?: string;\n redirect_uri?: string;\n }): string;\n getToken(code: string): Promise<{\n tokens: {\n access_token?: string | null;\n refresh_token?: string | null;\n expiry_date?: number | null;\n };\n }>;\n setCredentials(creds: { refresh_token?: string }): void;\n refreshAccessToken(): Promise<{\n credentials: { access_token?: string | null; expiry_date?: number | null };\n }>;\n}\n\n/** Build a real Google OAuth2 client for an installed/desktop app. */\nexport function createOAuthClient(\n clientId: string,\n clientSecret: string,\n redirectUri: string = DEFAULT_REDIRECT\n): GoogleOAuthClient {\n return new OAuth2Client(clientId, clientSecret, redirectUri) as unknown as GoogleOAuthClient;\n}\n\n/** The consent URL — offline access + forced consent so a refresh token is issued. */\nexport function buildAuthUrl(client: GoogleOAuthClient, redirectUri?: string): string {\n return client.generateAuthUrl({\n access_type: \"offline\",\n prompt: \"consent\",\n scope: GMAIL_IMAP_SCOPE,\n ...(redirectUri ? { redirect_uri: redirectUri } : {}),\n });\n}\n\n/** Exchange an authorization code for tokens. */\nexport async function exchangeCodeForTokens(\n client: GoogleOAuthClient,\n code: string,\n now: () => number = Date.now\n): Promise<GoogleTokens> {\n const { tokens } = await client.getToken(code);\n if (!tokens.access_token) throw new Error(\"Google did not return an access token\");\n return {\n accessToken: tokens.access_token,\n ...(tokens.refresh_token ? { refreshToken: tokens.refresh_token } : {}),\n expiresAt: tokens.expiry_date ?? now() + 3600_000,\n };\n}\n\n/** Mint a fresh access token from a stored refresh token. */\nexport async function refreshGoogleToken(\n clientId: string,\n clientSecret: string,\n refreshToken: string,\n clientFactory: (id: string, secret: string) => GoogleOAuthClient = createOAuthClient,\n now: () => number = Date.now\n): Promise<GoogleTokens> {\n const client = clientFactory(clientId, clientSecret);\n client.setCredentials({ refresh_token: refreshToken });\n const { credentials } = await client.refreshAccessToken();\n if (!credentials.access_token) throw new Error(\"Google refresh did not return an access token\");\n return {\n accessToken: credentials.access_token,\n refreshToken,\n expiresAt: credentials.expiry_date ?? now() + 3600_000,\n };\n}\n","// src/sync/oauth/microsoft.ts\n//\n// Microsoft OAuth2 *device code* flow for IMAP access (outlook.office365.com).\n// Device code suits a CLI: the user opens a URL on any device and enters a\n// short code — no local redirect server or client secret (public client).\n\nexport const MS_IMAP_SCOPE = \"offline_access https://outlook.office365.com/IMAP.AccessAsUser.All\";\n\ntype FetchFn = typeof fetch;\n\nfunction endpoint(tenant: string, kind: \"devicecode\" | \"token\"): string {\n return `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/${kind}`;\n}\n\nexport interface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval: number;\n message: string;\n}\n\nexport interface MicrosoftTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n}\n\n/** Start the device-code flow; returns the user code + verification URL to show. */\nexport async function requestDeviceCode(\n clientId: string,\n tenant = \"common\",\n fetchFn: FetchFn = fetch\n): Promise<DeviceCodeResponse> {\n const res = await fetchFn(endpoint(tenant, \"devicecode\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({ client_id: clientId, scope: MS_IMAP_SCOPE }).toString(),\n });\n if (!res.ok) throw new Error(`device code request failed: ${res.status} ${await res.text()}`);\n return (await res.json()) as DeviceCodeResponse;\n}\n\ninterface TokenSuccess {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n}\ninterface TokenError {\n error: string;\n error_description?: string;\n}\n\n/**\n * Poll the token endpoint until the user authorizes (or the code expires).\n * Honors `authorization_pending` (keep waiting) and `slow_down` (back off).\n */\nexport async function pollForToken(opts: {\n clientId: string;\n deviceCode: string;\n tenant?: string;\n interval?: number;\n expiresIn?: number;\n fetchFn?: FetchFn;\n sleepFn?: (ms: number) => Promise<void>;\n now?: () => number;\n}): Promise<MicrosoftTokens> {\n const tenant = opts.tenant ?? \"common\";\n const fetchFn = opts.fetchFn ?? fetch;\n const sleepFn = opts.sleepFn ?? ((ms) => new Promise((r) => setTimeout(r, ms)));\n const now = opts.now ?? Date.now;\n let intervalMs = (opts.interval ?? 5) * 1000;\n const deadline = now() + (opts.expiresIn ?? 900) * 1000;\n\n for (;;) {\n if (now() >= deadline) throw new Error(\"device code expired before authorization\");\n await sleepFn(intervalMs);\n\n const res = await fetchFn(endpoint(tenant, \"token\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n client_id: opts.clientId,\n device_code: opts.deviceCode,\n }).toString(),\n });\n\n const data = (await res.json()) as TokenSuccess | TokenError;\n if (res.ok && \"access_token\" in data) {\n return tokensFromSuccess(data, now());\n }\n const err = (data as TokenError).error;\n if (err === \"authorization_pending\") continue;\n if (err === \"slow_down\") {\n intervalMs += 5000;\n continue;\n }\n throw new Error(`device flow failed: ${err}${describe(data as TokenError)}`);\n }\n}\n\n/** Exchange a refresh token for a fresh access token. */\nexport async function refreshMicrosoftToken(\n clientId: string,\n refreshToken: string,\n tenant = \"common\",\n fetchFn: FetchFn = fetch,\n now: () => number = Date.now\n): Promise<MicrosoftTokens> {\n const res = await fetchFn(endpoint(tenant, \"token\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: MS_IMAP_SCOPE,\n }).toString(),\n });\n const data = (await res.json()) as TokenSuccess | TokenError;\n if (!res.ok || !(\"access_token\" in data)) {\n throw new Error(`token refresh failed: ${(data as TokenError).error ?? res.status}`);\n }\n return tokensFromSuccess(data, now());\n}\n\nfunction tokensFromSuccess(data: TokenSuccess, nowMs: number): MicrosoftTokens {\n return {\n accessToken: data.access_token,\n ...(data.refresh_token ? { refreshToken: data.refresh_token } : {}),\n expiresAt: nowMs + data.expires_in * 1000,\n };\n}\n\nfunction describe(e: TokenError): string {\n return e.error_description ? ` (${e.error_description.split(\"\\n\")[0]})` : \"\";\n}\n"],"mappings":"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"}
|