feat: basics #1
+31
-2
@@ -7,6 +7,24 @@ import { fileURLToPath } from "node:url";
|
|||||||
import { promisify } from "node:util";
|
import { promisify } from "node:util";
|
||||||
import type { Email, Folder, LoginConfig } from "./models.ts";
|
import type { Email, Folder, LoginConfig } from "./models.ts";
|
||||||
|
|
||||||
|
let inMemoryPassword: string | null = null;
|
||||||
|
|
||||||
|
export function setPassword(password: string): void {
|
||||||
|
inMemoryPassword = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPassword(): string | null {
|
||||||
|
return inMemoryPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasPassword(): boolean {
|
||||||
|
return inMemoryPassword !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearPassword(): void {
|
||||||
|
inMemoryPassword = null;
|
||||||
|
}
|
||||||
|
|
||||||
const ntlm: any = createRequire(import.meta.url)("httpntlm");
|
const ntlm: any = createRequire(import.meta.url)("httpntlm");
|
||||||
const postAsync = promisify(ntlm.post.bind(ntlm));
|
const postAsync = promisify(ntlm.post.bind(ntlm));
|
||||||
|
|
||||||
@@ -76,27 +94,38 @@ export function clearConfig(): void {
|
|||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
fs.unlinkSync(filePath);
|
fs.unlinkSync(filePath);
|
||||||
}
|
}
|
||||||
|
clearPassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EwsClient {
|
export class EwsClient {
|
||||||
private config: LoginConfig;
|
private config: LoginConfig;
|
||||||
private ewsUrl: string;
|
private ewsUrl: string;
|
||||||
|
|
||||||
constructor(config: LoginConfig) {
|
constructor(config: LoginConfig, password?: string) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.ewsUrl = `${config.serverUrl.replace(/\/+$/, "")}/EWS/Exchange.asmx`;
|
this.ewsUrl = `${config.serverUrl.replace(/\/+$/, "")}/EWS/Exchange.asmx`;
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
setPassword(password);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private get domain(): string {
|
private get domain(): string {
|
||||||
return this.config.domain ?? "corp";
|
return this.config.domain ?? "corp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get password(): string {
|
||||||
|
const pw = getPassword();
|
||||||
|
if (!pw) throw new Error("Not logged in. Password not found in memory.");
|
||||||
|
return pw;
|
||||||
|
}
|
||||||
|
|
||||||
private async soapRequest(body: string, soapAction: string): Promise<any> {
|
private async soapRequest(body: string, soapAction: string): Promise<any> {
|
||||||
const res = await postAsync({
|
const res = await postAsync({
|
||||||
url: this.ewsUrl,
|
url: this.ewsUrl,
|
||||||
username: this.config.username,
|
username: this.config.username,
|
||||||
domain: this.domain,
|
domain: this.domain,
|
||||||
password: this.config.password,
|
password: this.password,
|
||||||
agent: AGENT,
|
agent: AGENT,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "text/xml; charset=utf-8",
|
"Content-Type": "text/xml; charset=utf-8",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ export interface LoginConfig {
|
|||||||
serverUrl: string;
|
serverUrl: string;
|
||||||
email: string;
|
email: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
|
||||||
domain?: string;
|
domain?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-2
@@ -3,8 +3,10 @@ import { z } from "zod/v4";
|
|||||||
import {
|
import {
|
||||||
clearConfig,
|
clearConfig,
|
||||||
EwsClient,
|
EwsClient,
|
||||||
|
hasPassword,
|
||||||
loadConfig,
|
loadConfig,
|
||||||
saveConfig,
|
saveConfig,
|
||||||
|
setPassword,
|
||||||
} from "../ews_client.ts";
|
} from "../ews_client.ts";
|
||||||
|
|
||||||
export function registerAuthTools(server: McpServer): void {
|
export function registerAuthTools(server: McpServer): void {
|
||||||
@@ -28,11 +30,10 @@ export function registerAuthTools(server: McpServer): void {
|
|||||||
serverUrl: serverUrl.replace(/\/+$/, ""),
|
serverUrl: serverUrl.replace(/\/+$/, ""),
|
||||||
email,
|
email,
|
||||||
username,
|
username,
|
||||||
password,
|
|
||||||
domain: domain ?? "corp",
|
domain: domain ?? "corp",
|
||||||
};
|
};
|
||||||
|
|
||||||
const client = new EwsClient(config);
|
const client = new EwsClient(config, password);
|
||||||
const result = await client.verifyConnection();
|
const result = await client.verifyConnection();
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
@@ -80,6 +81,17 @@ export function registerAuthTools(server: McpServer): void {
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
|
if (!hasPassword()) {
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: "text" as const,
|
||||||
|
text: JSON.stringify({
|
||||||
|
authenticated: false,
|
||||||
|
error: "Not logged in. Password not found in memory.",
|
||||||
|
}),
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
}
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const client = new EwsClient(config);
|
const client = new EwsClient(config);
|
||||||
const result = await client.verifyConnection();
|
const result = await client.verifyConnection();
|
||||||
|
|||||||
Reference in New Issue
Block a user