@remit/backend 0.0.144 → 0.0.146

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 (91) hide show
  1. package/dist/src/api.d.ts +0 -2
  2. package/dist/src/api.js +9 -80
  3. package/dist/src/auth.d.ts +13 -19
  4. package/dist/src/auth.js +51 -43
  5. package/dist/src/config/api-config.d.ts +20 -0
  6. package/dist/src/config/api-config.js +1 -0
  7. package/dist/src/config/from-env.d.ts +2 -0
  8. package/dist/src/config/from-env.js +65 -0
  9. package/dist/src/config/msoauth-secrets-manager.d.ts +2 -0
  10. package/dist/src/config/msoauth-secrets-manager.js +28 -0
  11. package/dist/src/config/msoauth.d.ts +18 -29
  12. package/dist/src/config/msoauth.js +4 -28
  13. package/dist/src/derive/contentSignature.d.ts +3 -4
  14. package/dist/src/derive/contentSignature.js +4 -13
  15. package/dist/src/derive/contentUrl.d.ts +0 -13
  16. package/dist/src/derive/contentUrl.js +0 -19
  17. package/dist/src/handlers/account-oauth.d.ts +9 -3
  18. package/dist/src/handlers/account-oauth.js +197 -250
  19. package/dist/src/handlers/account.d.ts +13 -4
  20. package/dist/src/handlers/account.js +26 -39
  21. package/dist/src/handlers/address.d.ts +11 -3
  22. package/dist/src/handlers/address.js +11 -19
  23. package/dist/src/handlers/calendar-event.js +18 -26
  24. package/dist/src/handlers/calendar-feed.d.ts +2 -2
  25. package/dist/src/handlers/calendar-feed.js +24 -32
  26. package/dist/src/handlers/calendar-suggestion.js +18 -26
  27. package/dist/src/handlers/calendar.d.ts +1 -1
  28. package/dist/src/handlers/calendar.js +15 -22
  29. package/dist/src/handlers/config.d.ts +16 -6
  30. package/dist/src/handlers/config.js +23 -35
  31. package/dist/src/handlers/filter.d.ts +16 -3
  32. package/dist/src/handlers/filter.js +17 -32
  33. package/dist/src/handlers/folder-role.js +3 -6
  34. package/dist/src/handlers/index.d.ts +187 -2
  35. package/dist/src/handlers/index.js +6 -4
  36. package/dist/src/handlers/label.js +15 -22
  37. package/dist/src/handlers/mailbox.d.ts +20 -4
  38. package/dist/src/handlers/mailbox.js +18 -26
  39. package/dist/src/handlers/me.d.ts +10 -2
  40. package/dist/src/handlers/me.js +26 -47
  41. package/dist/src/handlers/message.d.ts +78 -6
  42. package/dist/src/handlers/message.js +34 -46
  43. package/dist/src/handlers/organize.d.ts +10 -4
  44. package/dist/src/handlers/organize.js +11 -20
  45. package/dist/src/handlers/outbox-attachment.d.ts +6 -5
  46. package/dist/src/handlers/outbox-attachment.js +11 -15
  47. package/dist/src/handlers/outbox.d.ts +25 -4
  48. package/dist/src/handlers/outbox.js +27 -35
  49. package/dist/src/handlers/sync.d.ts +19 -6
  50. package/dist/src/handlers/sync.js +13 -22
  51. package/dist/src/handlers/system-update.js +14 -27
  52. package/dist/src/handlers/thread.js +9 -14
  53. package/dist/src/handlers/unified-threads.js +3 -6
  54. package/dist/src/index.d.ts +4 -1
  55. package/dist/src/index.js +18 -2
  56. package/dist/src/jwt-auth.d.ts +9 -12
  57. package/dist/src/jwt-auth.js +19 -71
  58. package/dist/src/lambda.d.ts +13 -0
  59. package/dist/src/lambda.js +33 -0
  60. package/dist/src/request.d.ts +8 -2
  61. package/dist/src/request.js +16 -6
  62. package/dist/src/response.d.ts +20 -3
  63. package/dist/src/response.js +15 -22
  64. package/dist/src/serve.d.ts +31 -0
  65. package/dist/src/serve.js +117 -0
  66. package/dist/src/service/account-deletion.d.ts +2 -4
  67. package/dist/src/service/account-deletion.js +3 -9
  68. package/dist/src/service/compose-sqlite.d.ts +2 -1
  69. package/dist/src/service/compose-sqlite.js +5 -3
  70. package/dist/src/service/create-remit-client.d.ts +25 -11
  71. package/dist/src/service/create-remit-client.js +97 -116
  72. package/dist/src/service/data-client.js +3 -5
  73. package/dist/src/service/export-identity.d.ts +2 -1
  74. package/dist/src/service/export-identity.js +4 -6
  75. package/dist/src/service/fire-and-forget.js +1 -2
  76. package/dist/src/service/organize.d.ts +7 -10
  77. package/dist/src/service/organize.js +10 -27
  78. package/dist/src/service/queues.d.ts +12 -0
  79. package/dist/src/service/queues.js +1 -0
  80. package/dist/src/service/shared-deps.d.ts +6 -0
  81. package/dist/src/service/shared-deps.js +26 -0
  82. package/dist/src/service/trigger-sync.d.ts +11 -5
  83. package/dist/src/service/trigger-sync.js +10 -18
  84. package/dist/src/types.d.ts +24 -1
  85. package/package.json +24 -8
  86. package/dist/src/data-backend.d.ts +0 -12
  87. package/dist/src/data-backend.js +0 -12
  88. package/dist/src/request-context.d.ts +0 -9
  89. package/dist/src/request-context.js +0 -22
  90. package/dist/src/service/sqs.d.ts +0 -1
  91. package/dist/src/service/sqs.js +0 -3
@@ -2,22 +2,13 @@ import { importConfig, pendingImportOf, readConfigForExport, } from "@remit/conf
2
2
  import { ConfigNotEmptyError, NotFoundError } from "@remit/data-ports/errors";
3
3
  import { logger } from "@remit/logger";
4
4
  import { hasStoredCredential, } from "@remit/mailbox-service/account-credentials";
5
- import { env } from "expect-env";
6
- import { getAccountConfigIdFromEvent, getSubFromEvent } from "../auth.js";
7
- import { getClient } from "../service/data-client.js";
8
5
  import { exportIdentity } from "../service/export-identity.js";
9
6
  import { fireAndForget } from "../service/fire-and-forget.js";
10
- import { sqsClient } from "../service/sqs.js";
11
- import { triggerAccountSync } from "../service/trigger-sync.js";
7
+ import { triggerAccountSync, } from "../service/trigger-sync.js";
12
8
  import { toAccountResponse } from "./account-guards.js";
13
9
  import { groupAccountOverrides, } from "./account-overrides.js";
14
10
  import { groupSignaturesByAccount, } from "./account-signature.js";
15
11
  import { groupFolderAppointmentsByAccount, resolveFolderAppointments, writeFolderRoleAppointment, } from "./folder-role-appointments.js";
16
- const defaultConfigSyncTriggerDeps = () => ({
17
- sqsClient,
18
- queueUrl: env.SQS_QUEUE_URL,
19
- logger,
20
- });
21
12
  /**
22
13
  * Fire-and-forget sync trigger for the accounts surfaced by GET /config.
23
14
  *
@@ -44,11 +35,10 @@ const defaultConfigSyncTriggerDeps = () => ({
44
35
  * credential rather than `connectionState`, which stays `credentials_missing`
45
36
  * until a connect succeeds — see `hasStoredCredential`.
46
37
  */
47
- export const triggerConfigLoadSyncs = async (accountConfigId, accounts, deps = defaultConfigSyncTriggerDeps()) => {
38
+ export const triggerConfigLoadSyncs = async (accountConfigId, accounts, deps) => {
48
39
  await Promise.all(accounts.filter(hasStoredCredential).map(({ accountId }) => fireAndForget(async () => {
49
40
  const { eventId } = await triggerAccountSync({
50
- sqsClient: deps.sqsClient,
51
- queueUrl: deps.queueUrl,
41
+ queue: deps.queue,
52
42
  accountId,
53
43
  });
54
44
  deps.logger.info({ accountId, eventId }, "Sync triggered on config load");
@@ -68,7 +58,6 @@ const toAccountConfigResponse = (config) => ({
68
58
  createdAt: config.createdAt,
69
59
  updatedAt: config.updatedAt,
70
60
  });
71
- const buildCommit = () => process.env.REMIT_WORKER_SHA || process.env.GITHUB_SHA || "dev";
72
61
  /**
73
62
  * Returned by GET /config when no AccountConfig row exists yet for this user.
74
63
  * GET must never mutate state, so instead of creating a row we synthesize a
@@ -76,9 +65,8 @@ const buildCommit = () => process.env.REMIT_WORKER_SHA || process.env.GITHUB_SHA
76
65
  * The POST account-creation flow will materialize the real row when the user
77
66
  * adds their first account.
78
67
  */
79
- const emptyConfigResponse = (accountConfigId, event) => {
68
+ const emptyConfigResponse = (accountConfigId, userId, commit) => {
80
69
  const now = Date.now();
81
- const userId = getSubFromEvent(event) ?? accountConfigId;
82
70
  return {
83
71
  accountConfig: {
84
72
  accountConfigId,
@@ -88,14 +76,13 @@ const emptyConfigResponse = (accountConfigId, event) => {
88
76
  updatedAt: now,
89
77
  },
90
78
  accounts: [],
91
- buildCommit: buildCommit(),
79
+ buildCommit: commit,
92
80
  };
93
81
  };
94
82
  export const ConfigOperations = {
95
- ConfigOperations_getConfig: async (_context, ...args) => {
96
- const event = args[0];
97
- const accountConfigId = getAccountConfigIdFromEvent(event);
98
- const client = await getClient();
83
+ ConfigOperations_getConfig: async (_context, ctx) => {
84
+ const accountConfigId = ctx.identity.accountConfigId;
85
+ const client = ctx.client;
99
86
  const description = await client.accountConfig
100
87
  .describe(accountConfigId)
101
88
  .catch((err) => {
@@ -104,11 +91,11 @@ export const ConfigOperations = {
104
91
  throw err;
105
92
  });
106
93
  if (!description || description.accountConfig.length === 0) {
107
- return emptyConfigResponse(accountConfigId, event);
94
+ return emptyConfigResponse(accountConfigId, ctx.identity.sub, ctx.config.commit);
108
95
  }
109
96
  const accountConfig = description.accountConfig[0];
110
97
  if (!accountConfig) {
111
- return emptyConfigResponse(accountConfigId, event);
98
+ return emptyConfigResponse(accountConfigId, ctx.identity.sub, ctx.config.commit);
112
99
  }
113
100
  // Filter out deleted accounts (tombstone pattern)
114
101
  const activeAccounts = description.account.filter((acc) => acc.deletedAt === undefined);
@@ -135,35 +122,36 @@ export const ConfigOperations = {
135
122
  // triggerConfigLoadSyncs swallows nothing — it logs each failure loudly
136
123
  // with an alertable structured field — but it also never rejects, so the
137
124
  // `void` here cannot leak an unhandled rejection into a later request.
138
- void triggerConfigLoadSyncs(accountConfigId, activeAccounts);
125
+ void triggerConfigLoadSyncs(accountConfigId, activeAccounts, {
126
+ queue: ctx.client.queues.sync,
127
+ logger,
128
+ });
139
129
  // An import that named folders IMAP had not produced yet rides the config
140
130
  // read rather than a route of its own, so nothing has to poll for it.
141
131
  const pendingImport = pendingImportOf(await client.configImport.listByAccountConfig(accountConfigId));
142
132
  return {
143
133
  accountConfig: toAccountConfigResponse(accountConfig),
144
134
  ...(pendingImport ? { pendingImport } : {}),
145
- buildCommit: buildCommit(),
135
+ buildCommit: ctx.config.commit,
146
136
  accounts: activeAccounts.map((acc) => toAccountResponse(acc, signatureOf(acc.accountId), overridesOf(acc.accountId), resolveFolderAppointments(appointmentsByAccount.get(acc.accountId) ?? new Map(), mailboxesByAccount.get(acc.accountId) ?? []))),
147
137
  };
148
138
  },
149
- ConfigOperations_exportConfig: async (_context, ...args) => {
150
- const event = args[0];
151
- const accountConfigId = getAccountConfigIdFromEvent(event);
152
- const client = await getClient();
153
- const document = await readConfigForExport(client, accountConfigId, exportIdentity());
139
+ ConfigOperations_exportConfig: async (_context, ctx) => {
140
+ const accountConfigId = ctx.identity.accountConfigId;
141
+ const client = ctx.client;
142
+ const document = await readConfigForExport(client, accountConfigId, exportIdentity(ctx.config));
154
143
  return { schemaVersion: document.schemaVersion, document };
155
144
  },
156
- ConfigOperations_importConfig: async (context, ...args) => {
157
- const event = args[0];
158
- const accountConfigId = getAccountConfigIdFromEvent(event);
145
+ ConfigOperations_importConfig: async (context, ctx) => {
146
+ const accountConfigId = ctx.identity.accountConfigId;
159
147
  const body = (context.request.requestBody ?? {});
160
- const client = await getClient();
148
+ const client = ctx.client;
161
149
  const outcome = await importConfig({
162
150
  repositories: client,
163
151
  appointFolderRole: (configId, accountId, role, mailboxId, lastKnownPath) => writeFolderRoleAppointment(client.accountSetting, configId, accountId, role, mailboxId, lastKnownPath),
164
152
  }, {
165
153
  accountConfigId,
166
- userId: getSubFromEvent(event) ?? accountConfigId,
154
+ userId: ctx.identity.sub,
167
155
  document: body.document,
168
156
  mode: body.mode ?? "validate",
169
157
  onExisting: body.onExisting ?? "abort",
@@ -1,3 +1,16 @@
1
- import type { FilterDetailOperationIds, FilterOperationIds, OperationHandler } from "../types.js";
2
- export declare const FilterOperations: Record<FilterOperationIds, OperationHandler<FilterOperationIds>>;
3
- export declare const FilterDetailOperations: Record<FilterDetailOperationIds, OperationHandler<FilterDetailOperationIds>>;
1
+ import type { CreateFilterResponse } from "@remit/api-openapi-types";
2
+ import type { HandlerContext } from "../types.js";
3
+ export declare const FilterOperations: {
4
+ FilterOperations_listFilters: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: HandlerContext) => Promise<{
5
+ items: import("@remit/api-openapi-types").Components.Schemas.FilterResponse[];
6
+ continuationToken: string | undefined;
7
+ }>;
8
+ FilterOperations_createFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: HandlerContext<"accountFanout">) => Promise<CreateFilterResponse>;
9
+ };
10
+ export declare const FilterDetailOperations: {
11
+ FilterDetailOperations_getFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: HandlerContext) => Promise<import("@remit/api-openapi-types").Components.Schemas.FilterResponse>;
12
+ FilterDetailOperations_updateFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: HandlerContext) => Promise<import("@remit/api-openapi-types").Components.Schemas.FilterResponse>;
13
+ FilterDetailOperations_deleteFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: HandlerContext) => Promise<{
14
+ statusCode: number;
15
+ }>;
16
+ };
@@ -1,8 +1,5 @@
1
1
  import { logger } from "@remit/logger";
2
2
  import { createFilter, listFilters, ownedAccount, updateFilter, } from "@remit/mailbox-service";
3
- import { env } from "expect-env";
4
- import { getAccountConfigIdFromEvent, getSubFromEvent } from "../auth.js";
5
- import { getClient } from "../service/data-client.js";
6
3
  import { unwrap } from "../service/refusal.js";
7
4
  const toFilterResponse = (item) => ({
8
5
  filterId: item.filterId,
@@ -21,20 +18,12 @@ const toFilterResponse = (item) => ({
21
18
  createdAt: item.createdAt,
22
19
  updatedAt: item.updatedAt,
23
20
  });
24
- const requireUserId = (event) => {
25
- const userId = getSubFromEvent(event);
26
- if (!userId) {
27
- throw new Error("Missing Cognito `sub`: cannot attribute an organize job to a user");
28
- }
29
- return userId;
30
- };
31
21
  export const FilterOperations = {
32
- FilterOperations_listFilters: async (context, ...args) => {
33
- const event = args[0];
34
- const accountConfigId = getAccountConfigIdFromEvent(event);
22
+ FilterOperations_listFilters: async (context, ctx) => {
23
+ const accountConfigId = ctx.identity.accountConfigId;
35
24
  const { accountId } = context.request.params;
36
25
  const { continuationToken } = context.request.query;
37
- const page = unwrap(await listFilters(await getClient(), accountConfigId, {
26
+ const page = unwrap(await listFilters(ctx.client, accountConfigId, {
38
27
  accountId,
39
28
  continuationToken,
40
29
  }));
@@ -43,19 +32,18 @@ export const FilterOperations = {
43
32
  continuationToken: page.continuationToken,
44
33
  };
45
34
  },
46
- FilterOperations_createFilter: async (context, ...args) => {
47
- const event = args[0];
48
- const accountConfigId = getAccountConfigIdFromEvent(event);
35
+ FilterOperations_createFilter: async (context, ctx) => {
36
+ const accountConfigId = ctx.identity.accountConfigId;
49
37
  const { accountId } = context.request.params;
50
38
  const filter = context.request.requestBody;
51
- const userId = requireUserId(event);
52
- const client = await getClient();
39
+ const userId = ctx.identity.sub;
40
+ const client = ctx.client;
53
41
  const created = unwrap(await createFilter({
54
42
  account: client.account,
55
43
  mailbox: client.mailbox,
56
44
  filter: client.filter,
57
45
  organizeJobRequest: client.organizeJobRequest,
58
- sqsQueueUrl: env.SQS_QUEUE_URL_ACCOUNT_FANOUT,
46
+ queue: client.queues.accountFanout,
59
47
  logger,
60
48
  }, { accountConfigId, userId }, { accountId, filter }));
61
49
  return {
@@ -65,11 +53,10 @@ export const FilterOperations = {
65
53
  },
66
54
  };
67
55
  export const FilterDetailOperations = {
68
- FilterDetailOperations_getFilter: async (context, ...args) => {
69
- const event = args[0];
70
- const accountConfigId = getAccountConfigIdFromEvent(event);
56
+ FilterDetailOperations_getFilter: async (context, ctx) => {
57
+ const accountConfigId = ctx.identity.accountConfigId;
71
58
  const { accountId, filterId } = context.request.params;
72
- const client = await getClient();
59
+ const client = ctx.client;
73
60
  const account = await client.account.get(accountId);
74
61
  unwrap(ownedAccount(account, accountConfigId, "read"));
75
62
  const { filter } = client;
@@ -77,23 +64,21 @@ export const FilterDetailOperations = {
77
64
  const refreshed = await filter.refreshExpiry(item);
78
65
  return toFilterResponse(refreshed);
79
66
  },
80
- FilterDetailOperations_updateFilter: async (context, ...args) => {
81
- const event = args[0];
82
- const accountConfigId = getAccountConfigIdFromEvent(event);
67
+ FilterDetailOperations_updateFilter: async (context, ctx) => {
68
+ const accountConfigId = ctx.identity.accountConfigId;
83
69
  const { accountId, filterId } = context.request.params;
84
70
  const patch = context.request.requestBody;
85
- const updated = await updateFilter(await getClient(), accountConfigId, {
71
+ const updated = await updateFilter(ctx.client, accountConfigId, {
86
72
  accountId,
87
73
  filterId,
88
74
  patch,
89
75
  });
90
76
  return toFilterResponse(unwrap(updated));
91
77
  },
92
- FilterDetailOperations_deleteFilter: async (context, ...args) => {
93
- const event = args[0];
94
- const accountConfigId = getAccountConfigIdFromEvent(event);
78
+ FilterDetailOperations_deleteFilter: async (context, ctx) => {
79
+ const accountConfigId = ctx.identity.accountConfigId;
95
80
  const { accountId, filterId } = context.request.params;
96
- const client = await getClient();
81
+ const client = ctx.client;
97
82
  const account = await client.account.get(accountId);
98
83
  unwrap(ownedAccount(account, accountConfigId, "act"));
99
84
  const { filter } = client;
@@ -1,6 +1,4 @@
1
1
  import { folderInAccount, ownedAccount, settledFolder, } from "@remit/mailbox-service";
2
- import { getAccountConfigIdFromEvent } from "../auth.js";
3
- import { getClient } from "../service/data-client.js";
4
2
  import { unwrap } from "../service/refusal.js";
5
3
  import { toAccountResponse } from "./account-guards.js";
6
4
  import { loadAccountOverrides } from "./account-overrides.js";
@@ -14,12 +12,11 @@ import { resolveAccountFolderAppointments, writeFolderRoleAppointment, } from ".
14
12
  * the role back to unfilled.
15
13
  */
16
14
  export const FolderRoleOperations = {
17
- FolderRoleOperations_appointFolderRole: async (context, ...args) => {
18
- const event = args[0];
19
- const accountConfigId = getAccountConfigIdFromEvent(event);
15
+ FolderRoleOperations_appointFolderRole: async (context, ctx) => {
16
+ const accountConfigId = ctx.identity.accountConfigId;
20
17
  const { accountId, role } = context.request.params;
21
18
  const body = context.request.requestBody;
22
- const { account, accountSetting, mailbox } = await getClient();
19
+ const { account, accountSetting, mailbox } = ctx.client;
23
20
  const existing = await account.get(accountId);
24
21
  unwrap(ownedAccount(existing, accountConfigId, "act"));
25
22
  let lastKnownPath;
@@ -1,2 +1,187 @@
1
- import type { OperationHandler, OperationIds } from "../types.js";
2
- export declare const handlers: Record<OperationIds, OperationHandler<any>>;
1
+ import type { OperationHandler, PublicOperationHandler } from "../types.js";
2
+ export declare const handlers: {
3
+ CalendarSuggestionActionOperations_acceptCalendarSuggestion: OperationHandler<import("../types.js").CalendarSuggestionActionOperationIds>;
4
+ CalendarSuggestionActionOperations_declineCalendarSuggestion: OperationHandler<import("../types.js").CalendarSuggestionActionOperationIds>;
5
+ CalendarSuggestionActionOperations_dismissCalendarSuggestion: OperationHandler<import("../types.js").CalendarSuggestionActionOperationIds>;
6
+ CalendarSuggestionActionOperations_reopenCalendarSuggestion: OperationHandler<import("../types.js").CalendarSuggestionActionOperationIds>;
7
+ MessageCalendarSuggestionOperations_listMessageCalendarSuggestions: OperationHandler<"MessageCalendarSuggestionOperations_listMessageCalendarSuggestions">;
8
+ CalendarSuggestionOperations_listCalendarSuggestions: OperationHandler<"CalendarSuggestionOperations_listCalendarSuggestions">;
9
+ AddressDetailOperations_updateAddress: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").Components.Schemas.AddressResponse>;
10
+ AddressOperations_searchAddresses: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<{
11
+ items: import("@remit/api-openapi-types").Components.Schemas.AddressResponse[];
12
+ continuationToken: string | undefined;
13
+ }>;
14
+ OutboxAttachmentOperations_completeOutboxAttachment: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").OutboxAttachmentResponse | import("./outbox-attachment.js").RejectionResponse>;
15
+ OutboxDetailOperations_getOutboxMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").OutboxMessageResponse>;
16
+ OutboxDetailOperations_updateOutboxMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"smtp">) => Promise<import("@remit/api-openapi-types").OutboxMessageResponse>;
17
+ OutboxDetailOperations_deleteOutboxMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"smtp">) => Promise<{
18
+ statusCode: number;
19
+ }>;
20
+ OutboxDetailOperations_sendOutboxMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"smtp">) => Promise<import("@remit/api-openapi-types").OutboxMessageResponse>;
21
+ OutboxDetailOperations_mintOutboxAttachment: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").MintOutboxAttachmentResponse | import("./outbox-attachment.js").RejectionResponse>;
22
+ OutboxOperations_createOutboxMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"smtp">) => Promise<import("@remit/api-openapi-types").OutboxMessageResponse>;
23
+ OutboxOperations_listOutboxMessages: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<{
24
+ items: never[];
25
+ continuationToken: null;
26
+ } | {
27
+ items: import("@remit/api-openapi-types").Components.Schemas.OutboxMessageResponse[];
28
+ continuationToken: string | undefined;
29
+ }>;
30
+ MessageBulkOperations_updateFlags: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
31
+ successCount: number;
32
+ failureCount: number;
33
+ }>;
34
+ MessageBulkOperations_deleteMessages: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
35
+ successCount: number;
36
+ failureCount: number;
37
+ }>;
38
+ MessageBulkOperations_moveMessages: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
39
+ successCount: number;
40
+ failureCount: number;
41
+ }>;
42
+ MessageBulkOperations_copyMessages: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
43
+ successCount: number;
44
+ failureCount: number;
45
+ }>;
46
+ MessageBulkOperations_updateMessageLabels: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<{
47
+ successCount: number;
48
+ failureCount: number;
49
+ }>;
50
+ MessageBulkOperations_reportSpam: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("./message.js").SpamReportBulkOutcome>;
51
+ MessageBulkOperations_notSpam: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("./message.js").SpamReportBulkOutcome>;
52
+ MessageOperations_describeMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"sync" | "messageManagement" | "body">) => Promise<{
53
+ message: {
54
+ spamReport?: {
55
+ reportedAt: number;
56
+ } | undefined;
57
+ labels?: {
58
+ labelId: string;
59
+ name: string;
60
+ color: "Default" | "Red" | "Orange" | "Yellow" | "Green" | "Teal" | "Blue" | "Purple" | "Gray";
61
+ }[] | undefined;
62
+ autoMoved?: import("@remit/api-openapi-types").Components.Schemas.AutoMovedInfo | undefined;
63
+ messageId: string;
64
+ mailboxId: string;
65
+ uid: number;
66
+ rfc822Size: number;
67
+ internalDate: number;
68
+ messageIdHeader: string | undefined;
69
+ authenticity: {
70
+ fromDomain: string;
71
+ dkimMismatch: boolean;
72
+ dkimDomain?: string | undefined;
73
+ displayNameCorrespondence?: "Corresponds" | "Lookalike" | "ForeignAddress" | "Unrelated" | "NoClaim" | undefined;
74
+ offDomainLinkDomains?: string[] | undefined;
75
+ signerDomain?: string | undefined;
76
+ envelopeDomain?: string | undefined;
77
+ signerMessageCount?: number | undefined;
78
+ signerFirstSeenAt?: number | undefined;
79
+ } | undefined;
80
+ status: "active" | "deleting" | "deleted" | "moving";
81
+ syncStatus: "failed" | "synced" | "pending" | "abandoned";
82
+ abandonedMutation: "none" | "move" | "delete" | "copy";
83
+ };
84
+ envelope: import("@remit/api-openapi-types").Components.Schemas.EnvelopeResponse;
85
+ flags: string[];
86
+ bodyParts: import("@remit/api-openapi-types").Components.Schemas.BodyPartResponse[];
87
+ references: {
88
+ messageIdValue: string;
89
+ referenceType: string;
90
+ referenceOrder: number;
91
+ }[];
92
+ }>;
93
+ MessageOperations_getRawMessage: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"sync" | "messageManagement">) => Promise<{
94
+ raw: string;
95
+ }>;
96
+ MessageOperations_updateMessageFlags: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
97
+ messageId: string;
98
+ isRead: boolean;
99
+ isStarred: boolean;
100
+ }>;
101
+ ThreadOperations_listThreads: OperationHandler<import("../types.js").ThreadOperationIds>;
102
+ ThreadOperations_searchThreads: OperationHandler<import("../types.js").ThreadOperationIds>;
103
+ UnifiedThreadOperations_listAllThreads: OperationHandler<"UnifiedThreadOperations_listAllThreads">;
104
+ ThreadDetailOperations_listThreadMessages: OperationHandler<"ThreadDetailOperations_listThreadMessages">;
105
+ SyncOperations_triggerSync: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
106
+ triggered: boolean;
107
+ message: string;
108
+ }>;
109
+ SyncOperations_getSyncStatus: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<{
110
+ accountId: string;
111
+ syncPhase: "error" | "idle" | "discovering_mailboxes" | "syncing_inbox" | "syncing_others" | "complete" | undefined;
112
+ mailboxCountTotal: number | undefined;
113
+ mailboxCountSynced: number | undefined;
114
+ lastSyncAt: number | undefined;
115
+ mailboxes: import("./sync-progress.js").MailboxSyncProgress[];
116
+ }>;
117
+ TrashOperations_emptyTrash: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
118
+ deletedCount: number;
119
+ }>;
120
+ CalendarFreeBusyOperations_listCalendarFreeBusy: OperationHandler<"CalendarFreeBusyOperations_listCalendarFreeBusy">;
121
+ CalendarEventDetailOperations_getCalendarEvent: OperationHandler<import("../types.js").CalendarEventDetailOperationIds>;
122
+ CalendarEventDetailOperations_updateCalendarEvent: OperationHandler<import("../types.js").CalendarEventDetailOperationIds>;
123
+ CalendarEventDetailOperations_deleteCalendarEvent: OperationHandler<import("../types.js").CalendarEventDetailOperationIds>;
124
+ CalendarEventOperations_listCalendarEvents: OperationHandler<import("../types.js").CalendarEventOperationIds>;
125
+ CalendarEventOperations_createCalendarEvent: OperationHandler<import("../types.js").CalendarEventOperationIds>;
126
+ CalendarDetailOperations_getCalendarFeed: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
127
+ CalendarDetailOperations_putCalendarFeed: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
128
+ CalendarDetailOperations_revokeCalendarFeed: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
129
+ CalendarDetailOperations_getCalendar: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
130
+ CalendarDetailOperations_updateCalendar: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
131
+ CalendarDetailOperations_deleteCalendar: OperationHandler<import("../types.js").CalendarDetailOperationIds>;
132
+ CalendarOperations_listCalendars: OperationHandler<import("../types.js").CalendarOperationIds>;
133
+ CalendarOperations_createCalendar: OperationHandler<import("../types.js").CalendarOperationIds>;
134
+ OrganizeJobDetailOperations_getOrganizeJob: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").OrganizeJobResponse>;
135
+ OrganizeOperations_createOrganizeJob: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").CreateOrganizeJobResponse>;
136
+ OrganizeOperations_previewOrganize: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").OrganizePreviewResponse>;
137
+ LabelDetailOperations_getLabel: OperationHandler<import("../types.js").LabelDetailOperationIds>;
138
+ LabelDetailOperations_updateLabel: OperationHandler<import("../types.js").LabelDetailOperationIds>;
139
+ LabelDetailOperations_deleteLabel: OperationHandler<import("../types.js").LabelDetailOperationIds>;
140
+ LabelOperations_listLabels: OperationHandler<import("../types.js").LabelOperationIds>;
141
+ LabelOperations_createLabel: OperationHandler<import("../types.js").LabelOperationIds>;
142
+ FilterDetailOperations_getFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").Components.Schemas.FilterResponse>;
143
+ FilterDetailOperations_updateFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").Components.Schemas.FilterResponse>;
144
+ FilterDetailOperations_deleteFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<{
145
+ statusCode: number;
146
+ }>;
147
+ FilterOperations_listFilters: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<{
148
+ items: import("@remit/api-openapi-types").Components.Schemas.FilterResponse[];
149
+ continuationToken: string | undefined;
150
+ }>;
151
+ FilterOperations_createFilter: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").CreateFilterResponse>;
152
+ FolderRoleOperations_appointFolderRole: OperationHandler<"FolderRoleOperations_appointFolderRole">;
153
+ MailboxDetailOperations_getMailbox: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").Components.Schemas.MailboxResponse>;
154
+ MailboxDetailOperations_renameMailbox: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("@remit/api-openapi-types").Components.Schemas.MailboxResponse>;
155
+ MailboxDetailOperations_deleteMailbox: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<{
156
+ statusCode: number;
157
+ }>;
158
+ MailboxOperations_listMailboxes: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext) => Promise<{
159
+ items: import("@remit/api-openapi-types").Components.Schemas.MailboxResponse[];
160
+ continuationToken: string | undefined;
161
+ }>;
162
+ MailboxOperations_createMailbox: (context: import("openapi-backend").Context<any, any, any, any, any, import("openapi-backend").Document>, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("@remit/api-openapi-types").Components.Schemas.MailboxResponse>;
163
+ MicrosoftOAuthOperations_microsoftOAuthStart: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<{
164
+ authorizationUrl: string;
165
+ }>;
166
+ AccountDetailOperations_updateAccount: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").AccountResponse>;
167
+ AccountDetailOperations_deleteAccount: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").DeleteAccountResponse>;
168
+ AccountOperations_createAccount: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("@remit/api-openapi-types").AccountResponse>;
169
+ AccountOperations_testConnection: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").TestConnectionResponse>;
170
+ SystemOperations_getSystemUpdate: OperationHandler<import("../types.js").SystemOperationIds>;
171
+ SystemOperations_applySystemUpdate: OperationHandler<import("../types.js").SystemOperationIds>;
172
+ ConfigOperations_getConfig: (_context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"sync">) => Promise<import("@remit/api-openapi-types").ConfigDescriptionResponse>;
173
+ ConfigOperations_exportConfig: (_context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<{
174
+ schemaVersion: number;
175
+ document: import("@remit/config-format").ReaderConfigDocument;
176
+ }>;
177
+ ConfigOperations_importConfig: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").ConfigImportReport>;
178
+ MeOperations_listVipSuggestions: (_context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").VipSuggestionsResponse>;
179
+ MeOperations_listQuarantine: (_context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").QuarantineListResponse>;
180
+ MeOperations_deleteMe: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").DeleteAccountConfigResponse>;
181
+ MeOperations_createExport: (_context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext<"accountFanout">) => Promise<import("@remit/api-openapi-types").CreateExportResponse>;
182
+ MeOperations_getExport: (context: import("openapi-backend").Context, ctx: import("../types.js").HandlerContext) => Promise<import("@remit/api-openapi-types").AccountExportRequestResponse>;
183
+ };
184
+ export declare const publicHandlers: {
185
+ MicrosoftOAuthOperations_microsoftOAuthCallback: PublicOperationHandler<"sync">;
186
+ CalendarFeedOperations_getCalendarFeedIcal: PublicOperationHandler;
187
+ };
@@ -1,9 +1,9 @@
1
1
  import { AccountDetailOperations, AccountOperations } from "./account.js";
2
- import { MicrosoftOAuthOperations } from "./account-oauth.js";
2
+ import { MicrosoftOAuthOperations, microsoftOAuthCallback, } from "./account-oauth.js";
3
3
  import { AddressDetailOperations, AddressOperations } from "./address.js";
4
4
  import { CalendarDetailOperations, CalendarOperations } from "./calendar.js";
5
5
  import { CalendarEventDetailOperations, CalendarEventOperations, CalendarFreeBusyOperations, } from "./calendar-event.js";
6
- import { CalendarFeedDetailOperations, CalendarFeedOperations, } from "./calendar-feed.js";
6
+ import { CalendarFeedDetailOperations, getCalendarFeedIcal, } from "./calendar-feed.js";
7
7
  import { CalendarSuggestionActionOperations, CalendarSuggestionOperations, MessageCalendarSuggestionOperations, } from "./calendar-suggestion.js";
8
8
  import { ConfigOperations } from "./config.js";
9
9
  import { FilterDetailOperations, FilterOperations } from "./filter.js";
@@ -18,7 +18,6 @@ import { SyncOperations } from "./sync.js";
18
18
  import { SystemOperations } from "./system-update.js";
19
19
  import { ThreadDetailOperations, ThreadOperations } from "./thread.js";
20
20
  import { UnifiedThreadOperations } from "./unified-threads.js";
21
- // biome-ignore lint/suspicious/noExplicitAny: Types are narrowed downstream
22
21
  export const handlers = {
23
22
  ...MeOperations,
24
23
  ...ConfigOperations,
@@ -38,7 +37,6 @@ export const handlers = {
38
37
  ...CalendarOperations,
39
38
  ...CalendarDetailOperations,
40
39
  ...CalendarFeedDetailOperations,
41
- ...CalendarFeedOperations,
42
40
  ...CalendarEventOperations,
43
41
  ...CalendarEventDetailOperations,
44
42
  ...CalendarFreeBusyOperations,
@@ -58,3 +56,7 @@ export const handlers = {
58
56
  ...MessageCalendarSuggestionOperations,
59
57
  ...CalendarSuggestionActionOperations,
60
58
  };
59
+ export const publicHandlers = {
60
+ MicrosoftOAuthOperations_microsoftOAuthCallback: microsoftOAuthCallback,
61
+ CalendarFeedOperations_getCalendarFeedIcal: getCalendarFeedIcal,
62
+ };
@@ -1,6 +1,4 @@
1
1
  import { ownedAccount } from "@remit/mailbox-service";
2
- import { getAccountConfigIdFromEvent } from "../auth.js";
3
- import { getClient } from "../service/data-client.js";
4
2
  import { unwrap } from "../service/refusal.js";
5
3
  /**
6
4
  * Every filter in the account whose action applies this label (issue #26). The
@@ -39,12 +37,11 @@ export const deleteLabelWithCascade = async (deps, accountConfigId, labelId) =>
39
37
  await deps.label.delete(accountConfigId, labelId);
40
38
  };
41
39
  export const LabelOperations = {
42
- LabelOperations_listLabels: async (context, ...args) => {
43
- const event = args[0];
44
- const accountConfigId = getAccountConfigIdFromEvent(event);
40
+ LabelOperations_listLabels: async (context, ctx) => {
41
+ const accountConfigId = ctx.identity.accountConfigId;
45
42
  const { accountId } = context.request.params;
46
43
  const { continuationToken } = context.request.query;
47
- const client = await getClient();
44
+ const client = ctx.client;
48
45
  const account = await client.account.get(accountId);
49
46
  unwrap(ownedAccount(account, accountConfigId, "read"));
50
47
  const page = await client.label.listPageByAccountConfig(accountConfigId, {
@@ -61,12 +58,11 @@ export const LabelOperations = {
61
58
  continuationToken: page.continuationToken,
62
59
  };
63
60
  },
64
- LabelOperations_createLabel: async (context, ...args) => {
65
- const event = args[0];
66
- const accountConfigId = getAccountConfigIdFromEvent(event);
61
+ LabelOperations_createLabel: async (context, ctx) => {
62
+ const accountConfigId = ctx.identity.accountConfigId;
67
63
  const { accountId } = context.request.params;
68
64
  const input = context.request.requestBody;
69
- const client = await getClient();
65
+ const client = ctx.client;
70
66
  const account = await client.account.get(accountId);
71
67
  unwrap(ownedAccount(account, accountConfigId, "act"));
72
68
  const label = await client.label.create({
@@ -78,34 +74,31 @@ export const LabelOperations = {
78
74
  },
79
75
  };
80
76
  export const LabelDetailOperations = {
81
- LabelDetailOperations_getLabel: async (context, ...args) => {
82
- const event = args[0];
83
- const accountConfigId = getAccountConfigIdFromEvent(event);
77
+ LabelDetailOperations_getLabel: async (context, ctx) => {
78
+ const accountConfigId = ctx.identity.accountConfigId;
84
79
  const { accountId, labelId } = context.request.params;
85
- const client = await getClient();
80
+ const client = ctx.client;
86
81
  const account = await client.account.get(accountId);
87
82
  unwrap(ownedAccount(account, accountConfigId, "read"));
88
83
  const label = await client.label.get(accountConfigId, labelId);
89
84
  const filters = await findFiltersForLabel(client, accountConfigId, labelId);
90
85
  return toLabelResponse(label, filters.length);
91
86
  },
92
- LabelDetailOperations_updateLabel: async (context, ...args) => {
93
- const event = args[0];
94
- const accountConfigId = getAccountConfigIdFromEvent(event);
87
+ LabelDetailOperations_updateLabel: async (context, ctx) => {
88
+ const accountConfigId = ctx.identity.accountConfigId;
95
89
  const { accountId, labelId } = context.request.params;
96
90
  const body = context.request.requestBody;
97
- const client = await getClient();
91
+ const client = ctx.client;
98
92
  const account = await client.account.get(accountId);
99
93
  unwrap(ownedAccount(account, accountConfigId, "act"));
100
94
  const updated = await client.label.update(accountConfigId, labelId, body);
101
95
  const filters = await findFiltersForLabel(client, accountConfigId, labelId);
102
96
  return toLabelResponse(updated, filters.length);
103
97
  },
104
- LabelDetailOperations_deleteLabel: async (context, ...args) => {
105
- const event = args[0];
106
- const accountConfigId = getAccountConfigIdFromEvent(event);
98
+ LabelDetailOperations_deleteLabel: async (context, ctx) => {
99
+ const accountConfigId = ctx.identity.accountConfigId;
107
100
  const { accountId, labelId } = context.request.params;
108
- const client = await getClient();
101
+ const client = ctx.client;
109
102
  const account = await client.account.get(accountId);
110
103
  unwrap(ownedAccount(account, accountConfigId, "act"));
111
104
  await deleteLabelWithCascade(client, accountConfigId, labelId);