crewly 1.20.104 → 1.20.106

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.
Files changed (54) hide show
  1. package/config/skills/agent/core/todo-add/SKILL.md +64 -0
  2. package/config/skills/agent/core/todo-add/execute.sh +84 -0
  3. package/config/skills/agent/core/todo-add/execute.test.sh +76 -0
  4. package/config/skills/agent/core/todo-lists/SKILL.md +58 -0
  5. package/config/skills/agent/core/todo-lists/execute.sh +70 -0
  6. package/config/skills/agent/core/todo-lists/execute.test.sh +77 -0
  7. package/config/skills/agent/core/todo-tasks/SKILL.md +59 -0
  8. package/config/skills/agent/core/todo-tasks/execute.sh +78 -0
  9. package/config/skills/agent/core/todo-tasks/execute.test.sh +74 -0
  10. package/config/skills/agent/core/todo-update/SKILL.md +63 -0
  11. package/config/skills/agent/core/todo-update/execute.sh +115 -0
  12. package/config/skills/agent/core/todo-update/execute.test.sh +82 -0
  13. package/dist/backend/backend/src/constants.d.ts +65 -0
  14. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  15. package/dist/backend/backend/src/constants.js +65 -0
  16. package/dist/backend/backend/src/constants.js.map +1 -1
  17. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.d.ts +51 -0
  18. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.d.ts.map +1 -0
  19. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.js +223 -0
  20. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.js.map +1 -0
  21. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.d.ts +25 -0
  22. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.d.ts.map +1 -0
  23. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js +42 -0
  24. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js.map +1 -0
  25. package/dist/backend/backend/src/index.d.ts.map +1 -1
  26. package/dist/backend/backend/src/index.js +4 -9
  27. package/dist/backend/backend/src/index.js.map +1 -1
  28. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  29. package/dist/backend/backend/src/routes/api.routes.js +3 -0
  30. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  31. package/dist/backend/backend/src/services/agent/restore-filter.d.ts +37 -0
  32. package/dist/backend/backend/src/services/agent/restore-filter.d.ts.map +1 -0
  33. package/dist/backend/backend/src/services/agent/restore-filter.js +48 -0
  34. package/dist/backend/backend/src/services/agent/restore-filter.js.map +1 -0
  35. package/dist/backend/backend/src/services/connector/connector-access.service.d.ts +2 -2
  36. package/dist/backend/backend/src/services/connector/connector-access.service.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/connector/connector-access.service.js +2 -2
  38. package/dist/backend/backend/src/services/connector/connector-access.service.js.map +1 -1
  39. package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.d.ts +250 -0
  40. package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.d.ts.map +1 -0
  41. package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.js +367 -0
  42. package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.js.map +1 -0
  43. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.d.ts +116 -0
  44. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.d.ts.map +1 -0
  45. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js +220 -0
  46. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js.map +1 -0
  47. package/dist/backend/build-info.json +2 -2
  48. package/dist/cli/backend/src/constants.d.ts +65 -0
  49. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  50. package/dist/cli/backend/src/constants.js +65 -0
  51. package/dist/cli/backend/src/constants.js.map +1 -1
  52. package/frontend/dist/assets/{index-1fd45a2a.js → index-488339c1.js} +103 -103
  53. package/frontend/dist/index.html +1 -1
  54. package/package.json +1 -1
@@ -0,0 +1,367 @@
1
+ /**
2
+ * MicrosoftTodoService — Microsoft To Do over Graph v1.0 on the owner's grant.
3
+ *
4
+ * What agents can do: list task lists (and create one), list the tasks of a
5
+ * list (open ones by default), add a task (note, due date, importance),
6
+ * update a task (complete / reopen, retitle, re-date) and delete one.
7
+ *
8
+ * Lists are named by id or by display name (case-insensitive); no name at
9
+ * all means the owner's default list ("Tasks", `wellknownListName:
10
+ * defaultList`). Every call resolves the name against `GET /me/todo/lists`
11
+ * so the answer can say which list it acted on.
12
+ *
13
+ * Graph failures map to stable codes: 401 refreshes the token once, 429 is
14
+ * waited out once when `Retry-After` is short and otherwise returned as
15
+ * `rate_limited` with the delay, 403 → `forbidden`, 404 → `not_found`.
16
+ *
17
+ * @module services/microsoft/microsoft-todo.service
18
+ */
19
+ import { MICROSOFT_TODO_CONSTANTS } from '../../constants.js';
20
+ import { MicrosoftError } from './microsoft-token.service.js';
21
+ const CODES = MICROSOFT_TODO_CONSTANTS.ERROR_CODES;
22
+ /** Upper bound on `@odata.nextLink` pages followed when listing lists. */
23
+ const MAX_LIST_PAGES = 10;
24
+ const HTTP_NO_CONTENT = 204;
25
+ const MS_PER_SECOND = 1000;
26
+ /**
27
+ * Trim a Graph `todoTaskList`.
28
+ *
29
+ * @param l - Wire list
30
+ * @returns Trimmed list
31
+ */
32
+ export function toList(l) {
33
+ return {
34
+ id: l.id ?? '',
35
+ name: l.displayName ?? '',
36
+ ...(l.wellknownListName === MICROSOFT_TODO_CONSTANTS.DEFAULT_LIST_WELLKNOWN ? { isDefault: true } : {}),
37
+ ...(l.isShared ? { isShared: true } : {}),
38
+ };
39
+ }
40
+ /**
41
+ * Plain text of a task body (HTML bodies come from Outlook-created tasks).
42
+ *
43
+ * @param body - Wire body
44
+ * @returns Collapsed text, truncated to the preview length, or undefined
45
+ */
46
+ export function noteText(body) {
47
+ let text = body?.content ?? '';
48
+ if ((body?.contentType ?? '').toLowerCase() === 'html') {
49
+ text = text.replace(/<[^>]*>/g, ' ').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
50
+ }
51
+ text = text.replace(/\s+/g, ' ').trim();
52
+ if (!text)
53
+ return undefined;
54
+ const max = MICROSOFT_TODO_CONSTANTS.NOTE_PREVIEW_LENGTH;
55
+ return text.length > max ? `${text.slice(0, max)}…` : text;
56
+ }
57
+ /**
58
+ * Trim a Graph `todoTask`.
59
+ *
60
+ * @param t - Wire task
61
+ * @returns Trimmed task
62
+ */
63
+ export function toTask(t) {
64
+ const note = noteText(t.body);
65
+ const due = t.dueDateTime?.dateTime?.slice(0, 10);
66
+ const completedAt = t.status === 'completed' ? t.completedDateTime?.dateTime?.slice(0, 10) : undefined;
67
+ return {
68
+ id: t.id ?? '',
69
+ title: t.title ?? '',
70
+ status: t.status ?? 'notStarted',
71
+ ...(t.importance && t.importance !== 'normal' ? { importance: t.importance } : {}),
72
+ ...(due ? { due } : {}),
73
+ ...(note ? { note } : {}),
74
+ ...(completedAt ? { completedAt } : {}),
75
+ };
76
+ }
77
+ /**
78
+ * Validate a `YYYY-MM-DD` date and turn it into Graph's `dueDateTime`.
79
+ *
80
+ * @param value - Date text
81
+ * @returns `{ dateTime, timeZone }`
82
+ * @throws MicrosoftError(400, validation) for a malformed or impossible date
83
+ */
84
+ export function toDueDateTime(value) {
85
+ const text = value.trim();
86
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(text);
87
+ const parsed = match ? new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3]))) : null;
88
+ if (!match || !parsed || parsed.toISOString().slice(0, 10) !== text) {
89
+ throw new MicrosoftError(400, CODES.VALIDATION, `due must be a real date as YYYY-MM-DD (got "${value}")`);
90
+ }
91
+ return { dateTime: `${text}T00:00:00`, timeZone: MICROSOFT_TODO_CONSTANTS.DUE_TIME_ZONE };
92
+ }
93
+ /**
94
+ * Validate an importance value.
95
+ *
96
+ * @param value - Candidate
97
+ * @returns Lower-cased importance
98
+ * @throws MicrosoftError(400, validation) when unknown
99
+ */
100
+ export function toImportance(value) {
101
+ const v = value.trim().toLowerCase();
102
+ if (!MICROSOFT_TODO_CONSTANTS.IMPORTANCE_VALUES.includes(v)) {
103
+ throw new MicrosoftError(400, CODES.VALIDATION, `importance must be one of ${MICROSOFT_TODO_CONSTANTS.IMPORTANCE_VALUES.join(', ')}`);
104
+ }
105
+ return v;
106
+ }
107
+ /**
108
+ * Pick the list a reference names: exact id, then case-insensitive name,
109
+ * then `default` (or nothing) → the default list.
110
+ *
111
+ * @param lists - All lists
112
+ * @param ref - Id or name (may be empty)
113
+ * @returns The list
114
+ * @throws MicrosoftError(404, not_found) when nothing matches; (400, validation) when a name is ambiguous
115
+ */
116
+ export function pickList(lists, ref) {
117
+ const wanted = (ref ?? '').trim();
118
+ if (wanted) {
119
+ const byId = lists.find((l) => l.id === wanted);
120
+ if (byId)
121
+ return byId;
122
+ const byName = lists.filter((l) => l.name.trim().toLowerCase() === wanted.toLowerCase());
123
+ if (byName.length === 1)
124
+ return byName[0];
125
+ if (byName.length > 1) {
126
+ throw new MicrosoftError(400, CODES.VALIDATION, `Several lists are called "${wanted}"; pass the list id instead (${byName.map((l) => l.id).join(', ')})`);
127
+ }
128
+ if (wanted.toLowerCase() !== 'default') {
129
+ const names = lists.map((l) => l.name).join(', ');
130
+ throw new MicrosoftError(404, CODES.NOT_FOUND, `No To Do list called "${wanted}". Lists: ${names || '(none)'}`);
131
+ }
132
+ }
133
+ const fallback = lists.find((l) => l.isDefault) ?? lists[0];
134
+ if (!fallback)
135
+ throw new MicrosoftError(404, CODES.NOT_FOUND, 'This Microsoft account has no To Do lists.');
136
+ return fallback;
137
+ }
138
+ /**
139
+ * Microsoft To Do calls.
140
+ */
141
+ export class MicrosoftTodoService {
142
+ deps;
143
+ base = `${MICROSOFT_TODO_CONSTANTS.GRAPH_BASE}/me/todo/lists`;
144
+ /**
145
+ * @param deps - Token provider, fetch, sleep
146
+ */
147
+ constructor(deps) {
148
+ this.deps = {
149
+ ...deps,
150
+ fetchImpl: deps.fetchImpl ?? fetch,
151
+ sleep: deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms))),
152
+ };
153
+ }
154
+ /**
155
+ * `GET /me/todo/lists` (following `@odata.nextLink`).
156
+ *
157
+ * @returns Every list
158
+ */
159
+ async listLists() {
160
+ const out = [];
161
+ let url = this.base;
162
+ for (let page = 0; url && page < MAX_LIST_PAGES; page += 1) {
163
+ const data = await this.request(url);
164
+ out.push(...(data.value ?? []).map(toList));
165
+ url = data['@odata.nextLink'];
166
+ }
167
+ return out;
168
+ }
169
+ /**
170
+ * `POST /me/todo/lists`.
171
+ *
172
+ * @param name - Display name
173
+ * @returns The new list
174
+ * @throws MicrosoftError(400, validation) for an empty name
175
+ */
176
+ async createList(name) {
177
+ const displayName = (name ?? '').trim().slice(0, MICROSOFT_TODO_CONSTANTS.TITLE_MAX_LENGTH);
178
+ if (!displayName)
179
+ throw new MicrosoftError(400, CODES.VALIDATION, '"name" is required');
180
+ return toList(await this.request(this.base, { method: 'POST', body: { displayName } }));
181
+ }
182
+ /**
183
+ * Resolve a list reference (id, name, `default`, or empty).
184
+ *
185
+ * @param ref - Reference
186
+ * @returns The list
187
+ */
188
+ async resolveList(ref) {
189
+ return pickList(await this.listLists(), ref);
190
+ }
191
+ /**
192
+ * `GET /me/todo/lists/{id}/tasks` — open tasks unless `includeCompleted`.
193
+ *
194
+ * @param input - List, completed flag, limit
195
+ * @returns The list, its tasks, and whether more exist
196
+ */
197
+ async listTasks(input = {}) {
198
+ const list = await this.resolveList(input.list);
199
+ const limit = Math.min(Math.max(1, Math.floor(input.limit ?? MICROSOFT_TODO_CONSTANTS.TASKS_DEFAULT_LIMIT) || MICROSOFT_TODO_CONSTANTS.TASKS_DEFAULT_LIMIT), MICROSOFT_TODO_CONSTANTS.TASKS_LIMIT_CEILING);
200
+ const url = new URL(`${this.base}/${encodeURIComponent(list.id)}/tasks`);
201
+ url.searchParams.set('$top', String(limit));
202
+ if (!input.includeCompleted)
203
+ url.searchParams.set('$filter', "status ne 'completed'");
204
+ const data = await this.request(url.toString());
205
+ return { list: { id: list.id, name: list.name }, tasks: (data.value ?? []).map(toTask), hasMore: Boolean(data['@odata.nextLink']) };
206
+ }
207
+ /**
208
+ * `POST /me/todo/lists/{id}/tasks`.
209
+ *
210
+ * @param input - List, title, note, due, importance
211
+ * @returns The list and the new task
212
+ * @throws MicrosoftError(400, validation) for a missing title / bad due / bad importance
213
+ */
214
+ async addTask(input) {
215
+ const title = (input.title ?? '').trim().slice(0, MICROSOFT_TODO_CONSTANTS.TITLE_MAX_LENGTH);
216
+ if (!title)
217
+ throw new MicrosoftError(400, CODES.VALIDATION, '"title" is required');
218
+ const body = { title };
219
+ const note = (input.note ?? '').trim();
220
+ if (note)
221
+ body.body = { content: note.slice(0, MICROSOFT_TODO_CONSTANTS.NOTE_MAX_LENGTH), contentType: 'text' };
222
+ if (input.due?.trim())
223
+ body.dueDateTime = toDueDateTime(input.due);
224
+ if (input.importance?.trim())
225
+ body.importance = toImportance(input.importance);
226
+ const list = await this.resolveList(input.list);
227
+ const task = await this.request(`${this.base}/${encodeURIComponent(list.id)}/tasks`, { method: 'POST', body });
228
+ return { list: { id: list.id, name: list.name }, task: toTask(task) };
229
+ }
230
+ /**
231
+ * `PATCH /me/todo/lists/{id}/tasks/{taskId}`.
232
+ *
233
+ * @param input - List, task id, and the fields to change
234
+ * @returns The list and the updated task
235
+ * @throws MicrosoftError(400, validation) when nothing is changed or a value is bad
236
+ */
237
+ async updateTask(input) {
238
+ const taskId = (input.taskId ?? '').trim();
239
+ if (!taskId)
240
+ throw new MicrosoftError(400, CODES.VALIDATION, '"taskId" is required');
241
+ const body = {};
242
+ if (input.title !== undefined) {
243
+ const title = input.title.trim().slice(0, MICROSOFT_TODO_CONSTANTS.TITLE_MAX_LENGTH);
244
+ if (!title)
245
+ throw new MicrosoftError(400, CODES.VALIDATION, '"title" cannot be empty');
246
+ body.title = title;
247
+ }
248
+ if (input.note !== undefined)
249
+ body.body = { content: input.note.trim().slice(0, MICROSOFT_TODO_CONSTANTS.NOTE_MAX_LENGTH), contentType: 'text' };
250
+ if (input.due === null)
251
+ body.dueDateTime = null;
252
+ else if (input.due !== undefined)
253
+ body.dueDateTime = toDueDateTime(input.due);
254
+ if (input.importance !== undefined)
255
+ body.importance = toImportance(input.importance);
256
+ if (input.complete !== undefined)
257
+ body.status = input.complete ? 'completed' : 'notStarted';
258
+ if (Object.keys(body).length === 0) {
259
+ throw new MicrosoftError(400, CODES.VALIDATION, 'nothing to change: give complete, title, note, due or importance');
260
+ }
261
+ const list = await this.resolveList(input.list);
262
+ const task = await this.request(`${this.base}/${encodeURIComponent(list.id)}/tasks/${encodeURIComponent(taskId)}`, { method: 'PATCH', body });
263
+ return { list: { id: list.id, name: list.name }, task: toTask(task) };
264
+ }
265
+ /**
266
+ * `DELETE /me/todo/lists/{id}/tasks/{taskId}`.
267
+ *
268
+ * @param listRef - List id or name
269
+ * @param taskId - Task id
270
+ * @returns What was deleted
271
+ */
272
+ async deleteTask(listRef, taskId) {
273
+ const id = (taskId ?? '').trim();
274
+ if (!id)
275
+ throw new MicrosoftError(400, CODES.VALIDATION, '"taskId" is required');
276
+ const list = await this.resolveList(listRef);
277
+ await this.request(`${this.base}/${encodeURIComponent(list.id)}/tasks/${encodeURIComponent(id)}`, { method: 'DELETE' });
278
+ return { list: { id: list.id, name: list.name }, taskId: id, deleted: true };
279
+ }
280
+ // -------------------------------------------------------------------------
281
+ // Internals
282
+ // -------------------------------------------------------------------------
283
+ /**
284
+ * Authenticated Graph call.
285
+ *
286
+ * 401 → drop the cached token and retry once; still 401 → `unauthorized`.
287
+ * 429 → wait out a short `Retry-After` once, else `rate_limited`.
288
+ * 400 → `validation`, 403 → `forbidden`, 404 → `not_found`, others → 502.
289
+ *
290
+ * @param url - Absolute URL
291
+ * @param init - Method / JSON body
292
+ * @returns Parsed JSON (`{}` for 204)
293
+ */
294
+ async request(url, init = {}) {
295
+ let retriedAuth = false;
296
+ let retriedThrottle = false;
297
+ for (;;) {
298
+ const token = await this.deps.tokens.getAccessToken();
299
+ let res;
300
+ try {
301
+ res = await this.deps.fetchImpl(url, {
302
+ method: init.method ?? 'GET',
303
+ headers: {
304
+ Authorization: `Bearer ${token}`,
305
+ Accept: 'application/json',
306
+ ...(init.body !== undefined ? { 'Content-Type': 'application/json' } : {}),
307
+ },
308
+ body: init.body !== undefined ? JSON.stringify(init.body) : undefined,
309
+ signal: AbortSignal.timeout(MICROSOFT_TODO_CONSTANTS.REQUEST_TIMEOUT_MS),
310
+ });
311
+ }
312
+ catch (err) {
313
+ throw new MicrosoftError(502, CODES.NETWORK, `Microsoft Graph unreachable: ${err instanceof Error ? err.message : String(err)}`);
314
+ }
315
+ if (res.status === HTTP_NO_CONTENT)
316
+ return {};
317
+ const text = await res.text();
318
+ if (res.ok) {
319
+ if (!text)
320
+ return {};
321
+ try {
322
+ return JSON.parse(text);
323
+ }
324
+ catch {
325
+ throw new MicrosoftError(502, CODES.MICROSOFT_ERROR, 'Microsoft Graph returned a non-JSON response.');
326
+ }
327
+ }
328
+ let message = `Microsoft Graph request failed (${res.status})`;
329
+ let graphCode = '';
330
+ try {
331
+ const parsed = JSON.parse(text);
332
+ graphCode = parsed.error?.code ?? '';
333
+ message = parsed.error?.message || graphCode || message;
334
+ }
335
+ catch {
336
+ if (text)
337
+ message = text.slice(0, 200);
338
+ }
339
+ const detail = graphCode && !message.includes(graphCode) ? `${graphCode}: ${message}` : message;
340
+ if (res.status === 401) {
341
+ this.deps.tokens.clearCache();
342
+ if (!retriedAuth) {
343
+ retriedAuth = true;
344
+ continue;
345
+ }
346
+ throw new MicrosoftError(401, CODES.UNAUTHORIZED, `Microsoft rejected the access token: ${detail}`);
347
+ }
348
+ if (res.status === 429) {
349
+ const retryAfter = Math.max(1, Number.parseInt(res.headers?.get?.('Retry-After') ?? '', 10) || 1);
350
+ if (!retriedThrottle && retryAfter <= MICROSOFT_TODO_CONSTANTS.RETRY_AFTER_MAX_WAIT_S) {
351
+ retriedThrottle = true;
352
+ await this.deps.sleep(retryAfter * MS_PER_SECOND);
353
+ continue;
354
+ }
355
+ throw new MicrosoftError(429, CODES.RATE_LIMITED, `Microsoft Graph is throttling requests; retry after ${retryAfter}s`, retryAfter);
356
+ }
357
+ if (res.status === 400)
358
+ throw new MicrosoftError(400, CODES.VALIDATION, detail);
359
+ if (res.status === 403)
360
+ throw new MicrosoftError(403, CODES.FORBIDDEN, detail);
361
+ if (res.status === 404)
362
+ throw new MicrosoftError(404, CODES.NOT_FOUND, detail);
363
+ throw new MicrosoftError(502, CODES.MICROSOFT_ERROR, detail);
364
+ }
365
+ }
366
+ }
367
+ //# sourceMappingURL=microsoft-todo.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-todo.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/microsoft/microsoft-todo.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * MicrosoftTokenService — the Microsoft Graph access token for this
3
+ * instance, minted by Crewly Cloud from the owner's grant
4
+ * (`/api/cloud/microsoft/token`).
5
+ *
6
+ * Mirrors CanvaTokenService: Cloud keeps the client secret and the
7
+ * (rotating) refresh token; this side caches the access token until a
8
+ * minute before expiry and shares one in-flight refresh. The Cloud grant is
9
+ * keyed `microsoft`, so the same token will serve Outlook mail / calendar
10
+ * once those scopes are added — To Do is only its first consumer.
11
+ *
12
+ * @module services/microsoft/microsoft-token.service
13
+ */
14
+ /** The slice of the Cloud client the service needs (injectable for tests). */
15
+ export interface MicrosoftCloudClient {
16
+ isConnected(): boolean;
17
+ getToken(): string | null;
18
+ getCloudUrl(): string | null;
19
+ }
20
+ /** Constructor dependencies. */
21
+ export interface MicrosoftTokenServiceDeps {
22
+ cloud?: MicrosoftCloudClient;
23
+ fetchImpl?: typeof fetch;
24
+ now?: () => number;
25
+ }
26
+ /** `GET /api/microsoft-todo/status` payload. */
27
+ export interface MicrosoftStatus {
28
+ connected: boolean;
29
+ cloudConnected: boolean;
30
+ microsoftUserId?: string;
31
+ displayName?: string;
32
+ email?: string;
33
+ scopes?: string[];
34
+ grantedAt?: string;
35
+ }
36
+ /** A Microsoft / To Do failure with the HTTP status the controller answers with. */
37
+ export declare class MicrosoftError extends Error {
38
+ readonly status: number;
39
+ readonly code: string;
40
+ /** Seconds to wait before retrying (Graph 429 `Retry-After`). */
41
+ readonly retryAfterSeconds?: number | undefined;
42
+ constructor(status: number, code: string, message: string,
43
+ /** Seconds to wait before retrying (Graph 429 `Retry-After`). */
44
+ retryAfterSeconds?: number | undefined);
45
+ }
46
+ /**
47
+ * Map a Cloud grant-endpoint failure onto this instance's error codes.
48
+ *
49
+ * @param httpStatus - Cloud HTTP status
50
+ * @param code - Cloud `error` / `code`
51
+ * @param message - Cloud message
52
+ * @returns The mapped error
53
+ */
54
+ export declare function mapCloudFailure(httpStatus: number, code: string | undefined, message: string | undefined): MicrosoftError;
55
+ /**
56
+ * Access-token provider for Microsoft Graph.
57
+ */
58
+ export declare class MicrosoftTokenService {
59
+ private static instance;
60
+ private readonly logger;
61
+ private readonly cloud;
62
+ private readonly fetchImpl;
63
+ private readonly nowFn;
64
+ private cached;
65
+ private inflight;
66
+ constructor(deps?: MicrosoftTokenServiceDeps);
67
+ /**
68
+ * Process-wide instance.
69
+ *
70
+ * @returns The singleton
71
+ */
72
+ static getInstance(): MicrosoftTokenService;
73
+ /** Reset the singleton (tests). */
74
+ static resetInstance(): void;
75
+ /**
76
+ * Whether this instance is signed in to Crewly Cloud.
77
+ *
78
+ * @returns True when a Cloud session is available
79
+ */
80
+ isCloudAvailable(): boolean;
81
+ /**
82
+ * A usable access token (cached until 60 s before expiry).
83
+ *
84
+ * @returns The token
85
+ * @throws MicrosoftError not_logged_in / not_connected / not_configured / microsoft_error / network
86
+ */
87
+ getAccessToken(): Promise<string>;
88
+ /** Forget the cached token (after a Graph 401 or a disconnect). */
89
+ clearCache(): void;
90
+ /**
91
+ * Whether Cloud holds a Microsoft grant; "not there" cases come back as
92
+ * `connected: false`, outages throw.
93
+ *
94
+ * @returns Status
95
+ */
96
+ status(): Promise<MicrosoftStatus>;
97
+ /**
98
+ * Ask Cloud to forget the grant.
99
+ *
100
+ * @returns Whether Cloud had one
101
+ */
102
+ disconnect(): Promise<{
103
+ removed: boolean;
104
+ }>;
105
+ /**
106
+ * The Cloud consent-start URL for the browser.
107
+ *
108
+ * @param returnUrl - Absolute dashboard URL Cloud redirects back to
109
+ * @returns URL to open
110
+ * @throws MicrosoftError(401, not_logged_in) when not signed in to Cloud
111
+ */
112
+ buildConnectUrl(returnUrl: string): string;
113
+ private refresh;
114
+ private cloudRequest;
115
+ }
116
+ //# sourceMappingURL=microsoft-token.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-token.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/microsoft/microsoft-token.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC,WAAW,IAAI,OAAO,CAAC;IACvB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,gCAAgC;AAChC,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoBD,oFAAoF;AACpF,qBAAa,cAAe,SAAQ,KAAK;aAErB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;IAE5B,iEAAiE;aACjD,iBAAiB,CAAC,EAAE,MAAM;gBAJ1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM;IACf,iEAAiE;IACjD,iBAAiB,CAAC,EAAE,MAAM,YAAA;CAK7C;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAezH;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,MAAM,CAA6D;IAC3E,OAAO,CAAC,QAAQ,CAAgC;gBAEpC,IAAI,GAAE,yBAA8B;IAOhD;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,qBAAqB;IAK3C,mCAAmC;IACnC,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B;;;;OAIG;IACH,gBAAgB,IAAI,OAAO;IAI3B;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IASvC,mEAAmE;IACnE,UAAU,IAAI,IAAI;IAIlB;;;;;OAKG;IACG,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC;IAuBxC;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAMjD;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;YAY5B,OAAO;YAcP,YAAY;CA2B3B"}