@jbctechsolutions/mcp-office365 2.5.1
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/LICENSE +21 -0
- package/README.md +667 -0
- package/dist/applescript/account-repository.d.ts +30 -0
- package/dist/applescript/account-repository.d.ts.map +1 -0
- package/dist/applescript/account-repository.js +38 -0
- package/dist/applescript/account-repository.js.map +1 -0
- package/dist/applescript/account-scripts.d.ts +21 -0
- package/dist/applescript/account-scripts.d.ts.map +1 -0
- package/dist/applescript/account-scripts.js +180 -0
- package/dist/applescript/account-scripts.js.map +1 -0
- package/dist/applescript/calendar-manager.d.ts +44 -0
- package/dist/applescript/calendar-manager.d.ts.map +1 -0
- package/dist/applescript/calendar-manager.js +92 -0
- package/dist/applescript/calendar-manager.js.map +1 -0
- package/dist/applescript/calendar-writer.d.ts +36 -0
- package/dist/applescript/calendar-writer.d.ts.map +1 -0
- package/dist/applescript/calendar-writer.js +94 -0
- package/dist/applescript/calendar-writer.js.map +1 -0
- package/dist/applescript/content-readers.d.ts +114 -0
- package/dist/applescript/content-readers.d.ts.map +1 -0
- package/dist/applescript/content-readers.js +328 -0
- package/dist/applescript/content-readers.js.map +1 -0
- package/dist/applescript/executor.d.ts +60 -0
- package/dist/applescript/executor.d.ts.map +1 -0
- package/dist/applescript/executor.js +173 -0
- package/dist/applescript/executor.js.map +1 -0
- package/dist/applescript/index.d.ts +20 -0
- package/dist/applescript/index.d.ts.map +1 -0
- package/dist/applescript/index.js +29 -0
- package/dist/applescript/index.js.map +1 -0
- package/dist/applescript/mail-sender.d.ts +38 -0
- package/dist/applescript/mail-sender.d.ts.map +1 -0
- package/dist/applescript/mail-sender.js +67 -0
- package/dist/applescript/mail-sender.js.map +1 -0
- package/dist/applescript/parser.d.ts +235 -0
- package/dist/applescript/parser.d.ts.map +1 -0
- package/dist/applescript/parser.js +496 -0
- package/dist/applescript/parser.js.map +1 -0
- package/dist/applescript/repository.d.ts +64 -0
- package/dist/applescript/repository.d.ts.map +1 -0
- package/dist/applescript/repository.js +444 -0
- package/dist/applescript/repository.js.map +1 -0
- package/dist/applescript/scripts.d.ts +265 -0
- package/dist/applescript/scripts.d.ts.map +1 -0
- package/dist/applescript/scripts.js +1483 -0
- package/dist/applescript/scripts.js.map +1 -0
- package/dist/approval/hash.d.ts +87 -0
- package/dist/approval/hash.d.ts.map +1 -0
- package/dist/approval/hash.js +102 -0
- package/dist/approval/hash.js.map +1 -0
- package/dist/approval/index.d.ts +13 -0
- package/dist/approval/index.d.ts.map +1 -0
- package/dist/approval/index.js +7 -0
- package/dist/approval/index.js.map +1 -0
- package/dist/approval/token-manager.d.ts +51 -0
- package/dist/approval/token-manager.d.ts.map +1 -0
- package/dist/approval/token-manager.js +111 -0
- package/dist/approval/token-manager.js.map +1 -0
- package/dist/approval/types.d.ts +44 -0
- package/dist/approval/types.d.ts.map +1 -0
- package/dist/approval/types.js +6 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +143 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +42 -0
- package/dist/config.js.map +1 -0
- package/dist/database/connection.d.ts +77 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +130 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/index.d.ts +11 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +11 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/queries.d.ts +93 -0
- package/dist/database/queries.d.ts.map +1 -0
- package/dist/database/queries.js +430 -0
- package/dist/database/queries.js.map +1 -0
- package/dist/database/repository.d.ts +198 -0
- package/dist/database/repository.d.ts.map +1 -0
- package/dist/database/repository.js +199 -0
- package/dist/database/repository.js.map +1 -0
- package/dist/graph/attachments.d.ts +72 -0
- package/dist/graph/attachments.d.ts.map +1 -0
- package/dist/graph/attachments.js +207 -0
- package/dist/graph/attachments.js.map +1 -0
- package/dist/graph/auth/config.d.ts +34 -0
- package/dist/graph/auth/config.d.ts.map +1 -0
- package/dist/graph/auth/config.js +78 -0
- package/dist/graph/auth/config.js.map +1 -0
- package/dist/graph/auth/device-code-flow.d.ts +55 -0
- package/dist/graph/auth/device-code-flow.d.ts.map +1 -0
- package/dist/graph/auth/device-code-flow.js +180 -0
- package/dist/graph/auth/device-code-flow.js.map +1 -0
- package/dist/graph/auth/index.d.ts +13 -0
- package/dist/graph/auth/index.d.ts.map +1 -0
- package/dist/graph/auth/index.js +13 -0
- package/dist/graph/auth/index.js.map +1 -0
- package/dist/graph/auth/token-cache.d.ts +41 -0
- package/dist/graph/auth/token-cache.d.ts.map +1 -0
- package/dist/graph/auth/token-cache.js +105 -0
- package/dist/graph/auth/token-cache.js.map +1 -0
- package/dist/graph/client/batch.d.ts +38 -0
- package/dist/graph/client/batch.d.ts.map +1 -0
- package/dist/graph/client/batch.js +33 -0
- package/dist/graph/client/batch.js.map +1 -0
- package/dist/graph/client/cache.d.ts +64 -0
- package/dist/graph/client/cache.d.ts.map +1 -0
- package/dist/graph/client/cache.js +108 -0
- package/dist/graph/client/cache.js.map +1 -0
- package/dist/graph/client/graph-client.d.ts +630 -0
- package/dist/graph/client/graph-client.d.ts.map +1 -0
- package/dist/graph/client/graph-client.js +1771 -0
- package/dist/graph/client/graph-client.js.map +1 -0
- package/dist/graph/client/index.d.ts +12 -0
- package/dist/graph/client/index.d.ts.map +1 -0
- package/dist/graph/client/index.js +12 -0
- package/dist/graph/client/index.js.map +1 -0
- package/dist/graph/content-readers.d.ts +106 -0
- package/dist/graph/content-readers.d.ts.map +1 -0
- package/dist/graph/content-readers.js +321 -0
- package/dist/graph/content-readers.js.map +1 -0
- package/dist/graph/index.d.ts +18 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +23 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/mailbox-adapter.d.ts +30 -0
- package/dist/graph/mailbox-adapter.d.ts.map +1 -0
- package/dist/graph/mailbox-adapter.js +59 -0
- package/dist/graph/mailbox-adapter.js.map +1 -0
- package/dist/graph/mappers/contact-mapper.d.ts +14 -0
- package/dist/graph/mappers/contact-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/contact-mapper.js +20 -0
- package/dist/graph/mappers/contact-mapper.js.map +1 -0
- package/dist/graph/mappers/email-mapper.d.ts +14 -0
- package/dist/graph/mappers/email-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/email-mapper.js +44 -0
- package/dist/graph/mappers/email-mapper.js.map +1 -0
- package/dist/graph/mappers/event-mapper.d.ts +14 -0
- package/dist/graph/mappers/event-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/event-mapper.js +31 -0
- package/dist/graph/mappers/event-mapper.js.map +1 -0
- package/dist/graph/mappers/folder-mapper.d.ts +22 -0
- package/dist/graph/mappers/folder-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/folder-mapper.js +51 -0
- package/dist/graph/mappers/folder-mapper.js.map +1 -0
- package/dist/graph/mappers/index.d.ts +16 -0
- package/dist/graph/mappers/index.d.ts.map +1 -0
- package/dist/graph/mappers/index.js +16 -0
- package/dist/graph/mappers/index.js.map +1 -0
- package/dist/graph/mappers/task-mapper.d.ts +20 -0
- package/dist/graph/mappers/task-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/task-mapper.js +27 -0
- package/dist/graph/mappers/task-mapper.js.map +1 -0
- package/dist/graph/mappers/utils.d.ts +97 -0
- package/dist/graph/mappers/utils.d.ts.map +1 -0
- package/dist/graph/mappers/utils.js +186 -0
- package/dist/graph/mappers/utils.js.map +1 -0
- package/dist/graph/repository.d.ts +1104 -0
- package/dist/graph/repository.d.ts.map +1 -0
- package/dist/graph/repository.js +2999 -0
- package/dist/graph/repository.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6052 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/html-stripper.d.ts +41 -0
- package/dist/parsers/html-stripper.d.ts.map +1 -0
- package/dist/parsers/html-stripper.js +179 -0
- package/dist/parsers/html-stripper.js.map +1 -0
- package/dist/parsers/index.d.ts +12 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +12 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/olk15.d.ts +87 -0
- package/dist/parsers/olk15.d.ts.map +1 -0
- package/dist/parsers/olk15.js +368 -0
- package/dist/parsers/olk15.js.map +1 -0
- package/dist/signature.d.ts +22 -0
- package/dist/signature.d.ts.map +1 -0
- package/dist/signature.js +89 -0
- package/dist/signature.js.map +1 -0
- package/dist/tools/calendar-permissions.d.ts +79 -0
- package/dist/tools/calendar-permissions.d.ts.map +1 -0
- package/dist/tools/calendar-permissions.js +121 -0
- package/dist/tools/calendar-permissions.js.map +1 -0
- package/dist/tools/calendar.d.ts +208 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +247 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/categories.d.ts +94 -0
- package/dist/tools/categories.d.ts.map +1 -0
- package/dist/tools/categories.js +117 -0
- package/dist/tools/categories.js.map +1 -0
- package/dist/tools/checklist-items.d.ts +89 -0
- package/dist/tools/checklist-items.d.ts.map +1 -0
- package/dist/tools/checklist-items.js +140 -0
- package/dist/tools/checklist-items.js.map +1 -0
- package/dist/tools/contacts.d.ts +94 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +134 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/excel.d.ts +96 -0
- package/dist/tools/excel.d.ts.map +1 -0
- package/dist/tools/excel.js +165 -0
- package/dist/tools/excel.js.map +1 -0
- package/dist/tools/focused-overrides.d.ts +70 -0
- package/dist/tools/focused-overrides.d.ts.map +1 -0
- package/dist/tools/focused-overrides.js +117 -0
- package/dist/tools/focused-overrides.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +34 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/linked-resources.d.ts +74 -0
- package/dist/tools/linked-resources.d.ts.map +1 -0
- package/dist/tools/linked-resources.js +122 -0
- package/dist/tools/linked-resources.js.map +1 -0
- package/dist/tools/mail-rules.d.ts +98 -0
- package/dist/tools/mail-rules.d.ts.map +1 -0
- package/dist/tools/mail-rules.js +169 -0
- package/dist/tools/mail-rules.js.map +1 -0
- package/dist/tools/mail-send.d.ts +314 -0
- package/dist/tools/mail-send.d.ts.map +1 -0
- package/dist/tools/mail-send.js +555 -0
- package/dist/tools/mail-send.js.map +1 -0
- package/dist/tools/mail.d.ts +127 -0
- package/dist/tools/mail.d.ts.map +1 -0
- package/dist/tools/mail.js +311 -0
- package/dist/tools/mail.js.map +1 -0
- package/dist/tools/mailbox-organization.d.ts +301 -0
- package/dist/tools/mailbox-organization.d.ts.map +1 -0
- package/dist/tools/mailbox-organization.js +541 -0
- package/dist/tools/mailbox-organization.js.map +1 -0
- package/dist/tools/meetings.d.ts +114 -0
- package/dist/tools/meetings.d.ts.map +1 -0
- package/dist/tools/meetings.js +110 -0
- package/dist/tools/meetings.js.map +1 -0
- package/dist/tools/notes.d.ts +74 -0
- package/dist/tools/notes.d.ts.map +1 -0
- package/dist/tools/notes.js +136 -0
- package/dist/tools/notes.js.map +1 -0
- package/dist/tools/onedrive.d.ts +194 -0
- package/dist/tools/onedrive.d.ts.map +1 -0
- package/dist/tools/onedrive.js +257 -0
- package/dist/tools/onedrive.js.map +1 -0
- package/dist/tools/people.d.ts +129 -0
- package/dist/tools/people.d.ts.map +1 -0
- package/dist/tools/people.js +195 -0
- package/dist/tools/people.js.map +1 -0
- package/dist/tools/planner-visualization.d.ts +91 -0
- package/dist/tools/planner-visualization.d.ts.map +1 -0
- package/dist/tools/planner-visualization.js +192 -0
- package/dist/tools/planner-visualization.js.map +1 -0
- package/dist/tools/planner.d.ts +288 -0
- package/dist/tools/planner.d.ts.map +1 -0
- package/dist/tools/planner.js +368 -0
- package/dist/tools/planner.js.map +1 -0
- package/dist/tools/scheduling.d.ts +49 -0
- package/dist/tools/scheduling.d.ts.map +1 -0
- package/dist/tools/scheduling.js +115 -0
- package/dist/tools/scheduling.js.map +1 -0
- package/dist/tools/sharepoint.d.ts +115 -0
- package/dist/tools/sharepoint.d.ts.map +1 -0
- package/dist/tools/sharepoint.js +99 -0
- package/dist/tools/sharepoint.js.map +1 -0
- package/dist/tools/task-attachments.d.ts +74 -0
- package/dist/tools/task-attachments.d.ts.map +1 -0
- package/dist/tools/task-attachments.js +122 -0
- package/dist/tools/task-attachments.js.map +1 -0
- package/dist/tools/tasks.d.ts +74 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +126 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/teams.d.ts +389 -0
- package/dist/tools/teams.d.ts.map +1 -0
- package/dist/tools/teams.js +546 -0
- package/dist/tools/teams.js.map +1 -0
- package/dist/types/calendar.d.ts +60 -0
- package/dist/types/calendar.d.ts.map +1 -0
- package/dist/types/calendar.js +15 -0
- package/dist/types/calendar.js.map +1 -0
- package/dist/types/contacts.d.ts +96 -0
- package/dist/types/contacts.d.ts.map +1 -0
- package/dist/types/contacts.js +41 -0
- package/dist/types/contacts.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mail.d.ts +108 -0
- package/dist/types/mail.d.ts.map +1 -0
- package/dist/types/mail.js +40 -0
- package/dist/types/mail.js.map +1 -0
- package/dist/types/notes.d.ts +26 -0
- package/dist/types/notes.d.ts.map +1 -0
- package/dist/types/notes.js +6 -0
- package/dist/types/notes.js.map +1 -0
- package/dist/types/tasks.d.ts +31 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +6 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/utils/dates.d.ts +66 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +94 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/errors.d.ts +218 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +306 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/visualization/html.d.ts +26 -0
- package/dist/visualization/html.d.ts.map +1 -0
- package/dist/visualization/html.js +306 -0
- package/dist/visualization/html.js.map +1 -0
- package/dist/visualization/markdown.d.ts +25 -0
- package/dist/visualization/markdown.d.ts.map +1 -0
- package/dist/visualization/markdown.js +186 -0
- package/dist/visualization/markdown.js.map +1 -0
- package/dist/visualization/mermaid.d.ts +25 -0
- package/dist/visualization/mermaid.d.ts.map +1 -0
- package/dist/visualization/mermaid.js +158 -0
- package/dist/visualization/mermaid.js.map +1 -0
- package/dist/visualization/svg.d.ts +25 -0
- package/dist/visualization/svg.d.ts.map +1 -0
- package/dist/visualization/svg.js +282 -0
- package/dist/visualization/svg.js.map +1 -0
- package/dist/visualization/types.d.ts +43 -0
- package/dist/visualization/types.d.ts.map +1 -0
- package/dist/visualization/types.js +34 -0
- package/dist/visualization/types.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 JBC Tech Solutions, LLC
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root.
|
|
4
|
+
*/
|
|
5
|
+
import * as queries from './queries.js';
|
|
6
|
+
import { isoToAppleTimestamp } from '../utils/dates.js';
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Repository Implementation
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Repository implementation using better-sqlite3.
|
|
12
|
+
*/
|
|
13
|
+
export class OutlookRepository {
|
|
14
|
+
connection;
|
|
15
|
+
constructor(connection) {
|
|
16
|
+
this.connection = connection;
|
|
17
|
+
}
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Folders
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
listFolders() {
|
|
22
|
+
return this.connection.execute((db) => {
|
|
23
|
+
const stmt = db.prepare(queries.LIST_FOLDERS);
|
|
24
|
+
return stmt.all();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
getFolder(id) {
|
|
28
|
+
return this.connection.execute((db) => {
|
|
29
|
+
const stmt = db.prepare(queries.GET_FOLDER);
|
|
30
|
+
return stmt.get(id);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Emails
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
listEmails(folderId, limit, offset) {
|
|
37
|
+
return this.connection.execute((db) => {
|
|
38
|
+
const stmt = db.prepare(queries.LIST_EMAILS);
|
|
39
|
+
return stmt.all(folderId, limit, offset);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
listUnreadEmails(folderId, limit, offset) {
|
|
43
|
+
return this.connection.execute((db) => {
|
|
44
|
+
const stmt = db.prepare(queries.LIST_UNREAD_EMAILS);
|
|
45
|
+
return stmt.all(folderId, limit, offset);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
searchEmails(query, limit) {
|
|
49
|
+
return this.connection.execute((db) => {
|
|
50
|
+
const pattern = `%${query}%`;
|
|
51
|
+
const stmt = db.prepare(queries.SEARCH_EMAILS);
|
|
52
|
+
return stmt.all(pattern, pattern, pattern, limit);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
searchEmailsInFolder(folderId, query, limit) {
|
|
56
|
+
return this.connection.execute((db) => {
|
|
57
|
+
const pattern = `%${query}%`;
|
|
58
|
+
const stmt = db.prepare(queries.SEARCH_EMAILS_IN_FOLDER);
|
|
59
|
+
return stmt.all(folderId, pattern, pattern, pattern, limit);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
getEmail(id) {
|
|
63
|
+
return this.connection.execute((db) => {
|
|
64
|
+
const stmt = db.prepare(queries.GET_EMAIL);
|
|
65
|
+
return stmt.get(id);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
getUnreadCount() {
|
|
69
|
+
return this.connection.execute((db) => {
|
|
70
|
+
const stmt = db.prepare(queries.GET_UNREAD_COUNT);
|
|
71
|
+
const row = stmt.get();
|
|
72
|
+
return row?.count ?? 0;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
getUnreadCountByFolder(folderId) {
|
|
76
|
+
return this.connection.execute((db) => {
|
|
77
|
+
const stmt = db.prepare(queries.GET_UNREAD_COUNT_BY_FOLDER);
|
|
78
|
+
const row = stmt.get(folderId);
|
|
79
|
+
return row?.count ?? 0;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Calendar
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
listCalendars() {
|
|
86
|
+
return this.connection.execute((db) => {
|
|
87
|
+
const stmt = db.prepare(queries.LIST_CALENDARS);
|
|
88
|
+
return stmt.all();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
listEvents(limit) {
|
|
92
|
+
return this.connection.execute((db) => {
|
|
93
|
+
const stmt = db.prepare(queries.LIST_EVENTS);
|
|
94
|
+
return stmt.all(limit);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
listEventsByFolder(folderId, limit) {
|
|
98
|
+
return this.connection.execute((db) => {
|
|
99
|
+
const stmt = db.prepare(queries.LIST_EVENTS_BY_FOLDER);
|
|
100
|
+
return stmt.all(folderId, limit);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
listEventsByDateRange(startDate, endDate, limit) {
|
|
104
|
+
return this.connection.execute((db) => {
|
|
105
|
+
const stmt = db.prepare(queries.LIST_EVENTS_BY_DATE_RANGE);
|
|
106
|
+
return stmt.all(startDate, endDate, limit);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
searchEvents(query, startDate, endDate, limit) {
|
|
110
|
+
// SQLite doesn't have event titles in the database, so we can only filter by date range here.
|
|
111
|
+
// Title filtering must be done at a higher layer using content readers.
|
|
112
|
+
if (startDate != null && endDate != null) {
|
|
113
|
+
const startTs = isoToAppleTimestamp(startDate);
|
|
114
|
+
const endTs = isoToAppleTimestamp(endDate);
|
|
115
|
+
if (startTs != null && endTs != null) {
|
|
116
|
+
return this.listEventsByDateRange(startTs, endTs, limit);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return this.listEvents(limit);
|
|
120
|
+
}
|
|
121
|
+
getEvent(id) {
|
|
122
|
+
return this.connection.execute((db) => {
|
|
123
|
+
const stmt = db.prepare(queries.GET_EVENT);
|
|
124
|
+
return stmt.get(id);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Contacts
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
listContacts(limit, offset) {
|
|
131
|
+
return this.connection.execute((db) => {
|
|
132
|
+
const stmt = db.prepare(queries.LIST_CONTACTS);
|
|
133
|
+
return stmt.all(limit, offset);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
searchContacts(query, limit) {
|
|
137
|
+
return this.connection.execute((db) => {
|
|
138
|
+
const pattern = `%${query}%`;
|
|
139
|
+
const stmt = db.prepare(queries.SEARCH_CONTACTS);
|
|
140
|
+
return stmt.all(pattern, pattern, limit);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
getContact(id) {
|
|
144
|
+
return this.connection.execute((db) => {
|
|
145
|
+
const stmt = db.prepare(queries.GET_CONTACT);
|
|
146
|
+
return stmt.get(id);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// Tasks
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
listTasks(limit, offset) {
|
|
153
|
+
return this.connection.execute((db) => {
|
|
154
|
+
const stmt = db.prepare(queries.LIST_TASKS);
|
|
155
|
+
return stmt.all(limit, offset);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
listIncompleteTasks(limit, offset) {
|
|
159
|
+
return this.connection.execute((db) => {
|
|
160
|
+
const stmt = db.prepare(queries.LIST_INCOMPLETE_TASKS);
|
|
161
|
+
return stmt.all(limit, offset);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
searchTasks(query, limit) {
|
|
165
|
+
return this.connection.execute((db) => {
|
|
166
|
+
const pattern = `%${query}%`;
|
|
167
|
+
const stmt = db.prepare(queries.SEARCH_TASKS);
|
|
168
|
+
return stmt.all(pattern, limit);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
getTask(id) {
|
|
172
|
+
return this.connection.execute((db) => {
|
|
173
|
+
const stmt = db.prepare(queries.GET_TASK);
|
|
174
|
+
return stmt.get(id);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Notes
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
listNotes(limit, offset) {
|
|
181
|
+
return this.connection.execute((db) => {
|
|
182
|
+
const stmt = db.prepare(queries.LIST_NOTES);
|
|
183
|
+
return stmt.all(limit, offset);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
getNote(id) {
|
|
187
|
+
return this.connection.execute((db) => {
|
|
188
|
+
const stmt = db.prepare(queries.GET_NOTE);
|
|
189
|
+
return stmt.get(id);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Creates a repository with the given connection.
|
|
195
|
+
*/
|
|
196
|
+
export function createRepository(connection) {
|
|
197
|
+
return new OutlookRepository(connection);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/database/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 JBC Tech Solutions, LLC
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root.
|
|
4
|
+
*/
|
|
5
|
+
import type { GraphClient } from './client/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Returns the download directory for attachments.
|
|
8
|
+
*
|
|
9
|
+
* Reads `MCP_OUTLOOK_DOWNLOAD_DIR` env var, falls back to `os.tmpdir()`.
|
|
10
|
+
* Creates a subdirectory `mcp-outlook-attachments` inside it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getDownloadDir(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Sanitizes a filename to prevent path traversal attacks.
|
|
15
|
+
*
|
|
16
|
+
* Strips directory separators (`/`, `\`), strips `..` segments,
|
|
17
|
+
* and trims whitespace. Falls back to `'attachment'` if result is empty.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sanitizeFilename(name: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Generates a unique file path in the given directory.
|
|
22
|
+
*
|
|
23
|
+
* Sanitizes the filename, then checks if it already exists.
|
|
24
|
+
* If it does, appends a numeric suffix (e.g., `file(1).txt`, `file(2).txt`).
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveFilePath(downloadDir: string, filename: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Uploads a file as an attachment to a message.
|
|
29
|
+
*
|
|
30
|
+
* Routes based on file size:
|
|
31
|
+
* - <= 3MB: Inline base64 upload via `client.addAttachment`
|
|
32
|
+
* - > 3MB: Chunked upload session via `client.createUploadSession` + raw fetch
|
|
33
|
+
*
|
|
34
|
+
* @param client - The Graph API client
|
|
35
|
+
* @param messageId - The message to attach the file to
|
|
36
|
+
* @param filePath - Local path to the file to upload
|
|
37
|
+
* @param name - Optional display name (defaults to basename of filePath)
|
|
38
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
39
|
+
*/
|
|
40
|
+
export declare function uploadAttachment(client: GraphClient, messageId: string, filePath: string, name?: string, contentType?: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Uploads a file as an inline attachment (e.g. for cid: references in HTML body).
|
|
43
|
+
*
|
|
44
|
+
* Use this when the HTML body references the image via <img src="cid:contentId">.
|
|
45
|
+
* Keeps the body small by not embedding base64 in the MCP payload.
|
|
46
|
+
*
|
|
47
|
+
* Only supports files <= 3MB (same as regular inline upload).
|
|
48
|
+
*
|
|
49
|
+
* @param client - The Graph API client
|
|
50
|
+
* @param messageId - The message to attach the file to
|
|
51
|
+
* @param filePath - Local path to the image file
|
|
52
|
+
* @param contentId - Content-ID used in HTML (e.g. "logo" for cid:logo)
|
|
53
|
+
* @param contentType - Optional MIME type (defaults from file extension or image/png)
|
|
54
|
+
*/
|
|
55
|
+
export declare function uploadInlineAttachment(client: GraphClient, messageId: string, filePath: string, contentId: string, contentType?: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Downloads an attachment from a message and saves it to disk.
|
|
58
|
+
*
|
|
59
|
+
* Decodes `contentBytes` from base64 and writes the file to the download directory.
|
|
60
|
+
*
|
|
61
|
+
* @param client - The Graph API client
|
|
62
|
+
* @param messageId - The message containing the attachment
|
|
63
|
+
* @param attachmentId - The attachment to download
|
|
64
|
+
* @returns Metadata about the downloaded file including its local path
|
|
65
|
+
*/
|
|
66
|
+
export declare function downloadAttachment(client: GraphClient, messageId: string, attachmentId: string): Promise<{
|
|
67
|
+
filePath: string;
|
|
68
|
+
name: string;
|
|
69
|
+
size: number;
|
|
70
|
+
contentType: string;
|
|
71
|
+
}>;
|
|
72
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/graph/attachments.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAKvC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsDf;AAWD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBhF"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 JBC Tech Solutions, LLC
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Attachment upload and download helpers for Microsoft Graph API.
|
|
7
|
+
*
|
|
8
|
+
* Handles:
|
|
9
|
+
* - File I/O for reading/writing attachments
|
|
10
|
+
* - Size-based routing (inline vs chunked upload)
|
|
11
|
+
* - Chunked upload sessions for large files (> 3MB)
|
|
12
|
+
* - Safe filename resolution with path traversal prevention
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as os from 'os';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
/** 3MB threshold for inline vs chunked upload. */
|
|
18
|
+
const INLINE_MAX_BYTES = 3 * 1024 * 1024;
|
|
19
|
+
/** Microsoft's recommended chunk size (~3.75MB). */
|
|
20
|
+
const CHUNK_SIZE = 3932160;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the download directory for attachments.
|
|
23
|
+
*
|
|
24
|
+
* Reads `MCP_OUTLOOK_DOWNLOAD_DIR` env var, falls back to `os.tmpdir()`.
|
|
25
|
+
* Creates a subdirectory `mcp-outlook-attachments` inside it.
|
|
26
|
+
*/
|
|
27
|
+
export function getDownloadDir() {
|
|
28
|
+
const base = process.env['MCP_OUTLOOK_DOWNLOAD_DIR'] ?? os.tmpdir();
|
|
29
|
+
const dir = path.join(base, 'mcp-outlook-attachments');
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
31
|
+
return dir;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sanitizes a filename to prevent path traversal attacks.
|
|
35
|
+
*
|
|
36
|
+
* Strips directory separators (`/`, `\`), strips `..` segments,
|
|
37
|
+
* and trims whitespace. Falls back to `'attachment'` if result is empty.
|
|
38
|
+
*/
|
|
39
|
+
export function sanitizeFilename(name) {
|
|
40
|
+
// Strip .. segments
|
|
41
|
+
let sanitized = name.replace(/\.\./g, '');
|
|
42
|
+
// Take only the last component after any path separator
|
|
43
|
+
const forwardSlashIdx = sanitized.lastIndexOf('/');
|
|
44
|
+
if (forwardSlashIdx >= 0) {
|
|
45
|
+
sanitized = sanitized.substring(forwardSlashIdx + 1);
|
|
46
|
+
}
|
|
47
|
+
const backslashIdx = sanitized.lastIndexOf('\\');
|
|
48
|
+
if (backslashIdx >= 0) {
|
|
49
|
+
sanitized = sanitized.substring(backslashIdx + 1);
|
|
50
|
+
}
|
|
51
|
+
sanitized = sanitized.trim();
|
|
52
|
+
return sanitized.length > 0 ? sanitized : 'attachment';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generates a unique file path in the given directory.
|
|
56
|
+
*
|
|
57
|
+
* Sanitizes the filename, then checks if it already exists.
|
|
58
|
+
* If it does, appends a numeric suffix (e.g., `file(1).txt`, `file(2).txt`).
|
|
59
|
+
*/
|
|
60
|
+
export function resolveFilePath(downloadDir, filename) {
|
|
61
|
+
const safeName = sanitizeFilename(filename);
|
|
62
|
+
let candidate = path.join(downloadDir, safeName);
|
|
63
|
+
if (!fs.existsSync(candidate)) {
|
|
64
|
+
return candidate;
|
|
65
|
+
}
|
|
66
|
+
const ext = path.extname(safeName);
|
|
67
|
+
const base = safeName.substring(0, safeName.length - ext.length);
|
|
68
|
+
let counter = 1;
|
|
69
|
+
for (;;) { // eslint-disable-line no-constant-condition
|
|
70
|
+
candidate = path.join(downloadDir, `${base}(${counter})${ext}`);
|
|
71
|
+
if (!fs.existsSync(candidate)) {
|
|
72
|
+
return candidate;
|
|
73
|
+
}
|
|
74
|
+
counter++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Uploads a file as an attachment to a message.
|
|
79
|
+
*
|
|
80
|
+
* Routes based on file size:
|
|
81
|
+
* - <= 3MB: Inline base64 upload via `client.addAttachment`
|
|
82
|
+
* - > 3MB: Chunked upload session via `client.createUploadSession` + raw fetch
|
|
83
|
+
*
|
|
84
|
+
* @param client - The Graph API client
|
|
85
|
+
* @param messageId - The message to attach the file to
|
|
86
|
+
* @param filePath - Local path to the file to upload
|
|
87
|
+
* @param name - Optional display name (defaults to basename of filePath)
|
|
88
|
+
* @param contentType - Optional MIME type (defaults to 'application/octet-stream')
|
|
89
|
+
*/
|
|
90
|
+
export async function uploadAttachment(client, messageId, filePath, name, contentType) {
|
|
91
|
+
const fileName = name ?? path.basename(filePath);
|
|
92
|
+
const mimeType = contentType ?? 'application/octet-stream';
|
|
93
|
+
const stat = fs.statSync(filePath);
|
|
94
|
+
const fileSize = stat.size;
|
|
95
|
+
if (fileSize <= INLINE_MAX_BYTES) {
|
|
96
|
+
// Inline upload: read file, base64 encode, POST as attachment
|
|
97
|
+
const fileContent = fs.readFileSync(filePath);
|
|
98
|
+
const base64 = fileContent.toString('base64');
|
|
99
|
+
await client.addAttachment(messageId, {
|
|
100
|
+
'@odata.type': '#microsoft.graph.fileAttachment',
|
|
101
|
+
name: fileName,
|
|
102
|
+
contentBytes: base64,
|
|
103
|
+
contentType: mimeType,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Chunked upload session for large files
|
|
108
|
+
const session = await client.createUploadSession(messageId, {
|
|
109
|
+
AttachmentItem: {
|
|
110
|
+
attachmentType: 'file',
|
|
111
|
+
name: fileName,
|
|
112
|
+
size: fileSize,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const uploadUrl = session.uploadUrl;
|
|
116
|
+
const fileContent = fs.readFileSync(filePath);
|
|
117
|
+
let offset = 0;
|
|
118
|
+
while (offset < fileSize) {
|
|
119
|
+
const end = Math.min(offset + CHUNK_SIZE, fileSize);
|
|
120
|
+
const chunk = fileContent.subarray(offset, end);
|
|
121
|
+
const contentRange = `bytes ${offset}-${end - 1}/${fileSize}`;
|
|
122
|
+
const response = await fetch(uploadUrl, {
|
|
123
|
+
method: 'PUT',
|
|
124
|
+
headers: {
|
|
125
|
+
'Content-Range': contentRange,
|
|
126
|
+
'Content-Length': String(chunk.length),
|
|
127
|
+
},
|
|
128
|
+
body: chunk,
|
|
129
|
+
});
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(`Upload chunk failed: ${response.status} ${response.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
offset = end;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** MIME type by extension for inline images. */
|
|
138
|
+
const IMAGE_EXT_TO_MIME = {
|
|
139
|
+
'.png': 'image/png',
|
|
140
|
+
'.jpg': 'image/jpeg',
|
|
141
|
+
'.jpeg': 'image/jpeg',
|
|
142
|
+
'.gif': 'image/gif',
|
|
143
|
+
'.webp': 'image/webp',
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Uploads a file as an inline attachment (e.g. for cid: references in HTML body).
|
|
147
|
+
*
|
|
148
|
+
* Use this when the HTML body references the image via <img src="cid:contentId">.
|
|
149
|
+
* Keeps the body small by not embedding base64 in the MCP payload.
|
|
150
|
+
*
|
|
151
|
+
* Only supports files <= 3MB (same as regular inline upload).
|
|
152
|
+
*
|
|
153
|
+
* @param client - The Graph API client
|
|
154
|
+
* @param messageId - The message to attach the file to
|
|
155
|
+
* @param filePath - Local path to the image file
|
|
156
|
+
* @param contentId - Content-ID used in HTML (e.g. "logo" for cid:logo)
|
|
157
|
+
* @param contentType - Optional MIME type (defaults from file extension or image/png)
|
|
158
|
+
*/
|
|
159
|
+
export async function uploadInlineAttachment(client, messageId, filePath, contentId, contentType) {
|
|
160
|
+
const fileName = path.basename(filePath);
|
|
161
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
162
|
+
const mimeType = contentType ?? IMAGE_EXT_TO_MIME[ext] ?? 'image/png';
|
|
163
|
+
const stat = fs.statSync(filePath);
|
|
164
|
+
const fileSize = stat.size;
|
|
165
|
+
if (fileSize > INLINE_MAX_BYTES) {
|
|
166
|
+
throw new Error(`Inline image too large (${fileSize} bytes). Max ${INLINE_MAX_BYTES} bytes. Use a smaller image or attach as regular attachment.`);
|
|
167
|
+
}
|
|
168
|
+
const fileContent = fs.readFileSync(filePath);
|
|
169
|
+
const base64 = fileContent.toString('base64');
|
|
170
|
+
await client.addAttachment(messageId, {
|
|
171
|
+
'@odata.type': '#microsoft.graph.fileAttachment',
|
|
172
|
+
name: fileName,
|
|
173
|
+
contentBytes: base64,
|
|
174
|
+
contentType: mimeType,
|
|
175
|
+
isInline: true,
|
|
176
|
+
contentId,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Downloads an attachment from a message and saves it to disk.
|
|
181
|
+
*
|
|
182
|
+
* Decodes `contentBytes` from base64 and writes the file to the download directory.
|
|
183
|
+
*
|
|
184
|
+
* @param client - The Graph API client
|
|
185
|
+
* @param messageId - The message containing the attachment
|
|
186
|
+
* @param attachmentId - The attachment to download
|
|
187
|
+
* @returns Metadata about the downloaded file including its local path
|
|
188
|
+
*/
|
|
189
|
+
export async function downloadAttachment(client, messageId, attachmentId) {
|
|
190
|
+
const attachment = await client.getAttachment(messageId, attachmentId);
|
|
191
|
+
const rawName = attachment.name ?? '';
|
|
192
|
+
const safeName = sanitizeFilename(rawName);
|
|
193
|
+
const size = attachment.size ?? 0;
|
|
194
|
+
const attachmentContentType = attachment.contentType ?? 'application/octet-stream';
|
|
195
|
+
const downloadDir = getDownloadDir();
|
|
196
|
+
const filePath = resolveFilePath(downloadDir, safeName);
|
|
197
|
+
const contentBytes = attachment.contentBytes ?? '';
|
|
198
|
+
const buffer = Buffer.from(contentBytes, 'base64');
|
|
199
|
+
fs.writeFileSync(filePath, buffer);
|
|
200
|
+
return {
|
|
201
|
+
filePath,
|
|
202
|
+
name: safeName,
|
|
203
|
+
size,
|
|
204
|
+
contentType: attachmentContentType,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/graph/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 JBC Tech Solutions, LLC
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Microsoft Graph API scopes required for Outlook access.
|
|
7
|
+
*
|
|
8
|
+
* Includes read/write permissions for mail and calendars to support
|
|
9
|
+
* future implementation of email sending and event management features.
|
|
10
|
+
*/
|
|
11
|
+
export declare const GRAPH_SCOPES: readonly ["Mail.ReadWrite", "Calendars.ReadWrite", "Contacts.ReadWrite", "Tasks.ReadWrite", "User.Read", "offline_access", "ChannelMessage.Read.All", "ChannelMessage.Send", "Channel.ReadBasic.All", "Team.ReadBasic.All", "Chat.ReadWrite", "ChatMessage.Send", "People.Read", "User.ReadBasic.All", "Presence.Read.All", "Group.Read.All"];
|
|
12
|
+
/**
|
|
13
|
+
* Microsoft Graph API configuration.
|
|
14
|
+
*/
|
|
15
|
+
export interface GraphAuthConfig {
|
|
16
|
+
/** Azure AD application (client) ID */
|
|
17
|
+
readonly clientId: string;
|
|
18
|
+
/** Azure AD tenant ID (default: 'common' for multi-tenant) */
|
|
19
|
+
readonly tenantId: string;
|
|
20
|
+
/** OAuth2 scopes to request */
|
|
21
|
+
readonly scopes: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Loads the Graph API configuration.
|
|
25
|
+
*
|
|
26
|
+
* Uses embedded defaults but allows override via environment variables
|
|
27
|
+
* for users who want to use their own Azure AD app registration.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadGraphConfig(): GraphAuthConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the Azure AD authority URL for the configured tenant.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getAuthorityUrl(config: GraphAuthConfig): string;
|
|
34
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/graph/auth/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,+UAqBf,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAiBjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 JBC Tech Solutions, LLC
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Microsoft Graph API configuration.
|
|
7
|
+
*
|
|
8
|
+
* Contains Azure AD app registration settings for the device code flow.
|
|
9
|
+
* The client ID is embedded in the package - users don't need to configure anything.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Default client ID for the Outlook MCP Server Azure AD app.
|
|
13
|
+
*
|
|
14
|
+
* This is a public client application registered in Azure AD by JBC Tech Solutions.
|
|
15
|
+
* Multi-tenant configuration supports both personal and work/school Microsoft accounts.
|
|
16
|
+
*
|
|
17
|
+
* Users can override this with their own app registration by setting:
|
|
18
|
+
* - OUTLOOK_MCP_CLIENT_ID environment variable
|
|
19
|
+
* - OUTLOOK_MCP_TENANT_ID environment variable (default: 'common')
|
|
20
|
+
*
|
|
21
|
+
* For setup instructions: https://github.com/jbctechsolutions/mcp-office365#custom-azure-ad-setup
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULT_CLIENT_ID = '681fbb29-5afa-47b1-9c16-0cd2be01754d';
|
|
24
|
+
/**
|
|
25
|
+
* Microsoft Graph API scopes required for Outlook access.
|
|
26
|
+
*
|
|
27
|
+
* Includes read/write permissions for mail and calendars to support
|
|
28
|
+
* future implementation of email sending and event management features.
|
|
29
|
+
*/
|
|
30
|
+
export const GRAPH_SCOPES = [
|
|
31
|
+
// Outlook
|
|
32
|
+
'Mail.ReadWrite',
|
|
33
|
+
'Calendars.ReadWrite',
|
|
34
|
+
'Contacts.ReadWrite',
|
|
35
|
+
'Tasks.ReadWrite',
|
|
36
|
+
'User.Read',
|
|
37
|
+
'offline_access',
|
|
38
|
+
// Teams
|
|
39
|
+
'ChannelMessage.Read.All',
|
|
40
|
+
'ChannelMessage.Send',
|
|
41
|
+
'Channel.ReadBasic.All',
|
|
42
|
+
'Team.ReadBasic.All',
|
|
43
|
+
'Chat.ReadWrite',
|
|
44
|
+
'ChatMessage.Send',
|
|
45
|
+
// People & Presence
|
|
46
|
+
'People.Read',
|
|
47
|
+
'User.ReadBasic.All',
|
|
48
|
+
'Presence.Read.All',
|
|
49
|
+
// Planner
|
|
50
|
+
'Group.Read.All',
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Loads the Graph API configuration.
|
|
54
|
+
*
|
|
55
|
+
* Uses embedded defaults but allows override via environment variables
|
|
56
|
+
* for users who want to use their own Azure AD app registration.
|
|
57
|
+
*/
|
|
58
|
+
export function loadGraphConfig() {
|
|
59
|
+
const clientId = process.env['OUTLOOK_MCP_CLIENT_ID'] ?? DEFAULT_CLIENT_ID;
|
|
60
|
+
const tenantId = process.env['OUTLOOK_MCP_TENANT_ID'] ?? 'common';
|
|
61
|
+
if (clientId === 'YOUR_AZURE_APP_CLIENT_ID') {
|
|
62
|
+
throw new Error('Azure AD app not configured. Either:\n' +
|
|
63
|
+
'1. Set OUTLOOK_MCP_CLIENT_ID environment variable, or\n' +
|
|
64
|
+
'2. The package maintainer needs to embed the client ID in config.ts');
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
clientId,
|
|
68
|
+
tenantId,
|
|
69
|
+
scopes: [...GRAPH_SCOPES],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Gets the Azure AD authority URL for the configured tenant.
|
|
74
|
+
*/
|
|
75
|
+
export function getAuthorityUrl(config) {
|
|
76
|
+
return `https://login.microsoftonline.com/${config.tenantId}`;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/graph/auth/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU;IACV,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB;IACpB,iBAAiB;IACjB,WAAW;IACX,gBAAgB;IAChB,QAAQ;IACR,yBAAyB;IACzB,qBAAqB;IACrB,uBAAuB;IACvB,oBAAoB;IACpB,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,aAAa;IACb,oBAAoB;IACpB,mBAAmB;IACnB,UAAU;IACV,gBAAgB;CACR,CAAC;AAcX;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,iBAAiB,CAAC;IAC3E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,QAAQ,CAAC;IAElE,IAAI,QAAQ,KAAK,0BAA0B,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,wCAAwC;YACtC,yDAAyD;YACzD,qEAAqE,CACxE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAuB;IACrD,OAAO,qCAAqC,MAAM,CAAC,QAAQ,EAAE,CAAC;AAChE,CAAC"}
|