@remit/backend 0.0.112 → 0.0.114
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/dev-server/server.ts +3 -4
- package/package.json +1 -1
- package/src/handlers/mailbox.ts +13 -25
package/dev-server/server.ts
CHANGED
|
@@ -97,11 +97,10 @@ if (isSelfHostBackend) {
|
|
|
97
97
|
},
|
|
98
98
|
);
|
|
99
99
|
|
|
100
|
-
const { createAuth, resolveAuthConfig, toNodeHandler } =
|
|
101
|
-
"@remit/auth-service"
|
|
102
|
-
);
|
|
100
|
+
const { createAuth, resolveAuthConfig, toNodeHandler, withRateLimitLogging } =
|
|
101
|
+
await import("@remit/auth-service");
|
|
103
102
|
const auth = await createAuth(resolveAuthConfig());
|
|
104
|
-
app.all(/^\/api\/auth\//, toNodeHandler(auth));
|
|
103
|
+
app.all(/^\/api\/auth\//, toNodeHandler(withRateLimitLogging(auth)));
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
// Ahead of the body parsers, not after them: a body refused for its size never
|
package/package.json
CHANGED
package/src/handlers/mailbox.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type CanonicalMailboxRoleValue,
|
|
9
9
|
composeFolderRoleAppointmentLabelName,
|
|
10
10
|
} from "@remit/data-ports/folder-role";
|
|
11
|
+
import { rebaseMailboxPath } from "@remit/data-ports/mailbox-name";
|
|
11
12
|
import { MailboxSyncStatus, MessageSystemFlag } from "@remit/domain-enums";
|
|
12
13
|
import type { APIGatewayProxyEvent } from "aws-lambda";
|
|
13
14
|
import { getAccountConfigIdFromEvent } from "../auth.js";
|
|
@@ -76,24 +77,6 @@ export interface MailboxPatchClient {
|
|
|
76
77
|
accountSetting: Pick<IAccountSettingRepository, "get" | "upsert" | "delete">;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
/**
|
|
80
|
-
* Where a recorded path lands after the rename, or `undefined` when the rename
|
|
81
|
-
* did not move it. IMAP RENAME moves the whole subtree in one command and
|
|
82
|
-
* `renameChildPaths` rewrites every descendant row with it, so a label under
|
|
83
|
-
* the renamed branch moves exactly as far as its prefix does.
|
|
84
|
-
*/
|
|
85
|
-
const rebasePath = (
|
|
86
|
-
recorded: string,
|
|
87
|
-
oldPath: string,
|
|
88
|
-
newPath: string,
|
|
89
|
-
delimiter: string,
|
|
90
|
-
): string | undefined => {
|
|
91
|
-
if (recorded === oldPath) return newPath;
|
|
92
|
-
const branch = `${oldPath}${delimiter}`;
|
|
93
|
-
if (!recorded.startsWith(branch)) return undefined;
|
|
94
|
-
return `${newPath}${recorded.slice(oldPath.length)}`;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
80
|
/**
|
|
98
81
|
* A reader-side rename keeps every mailboxId, so the appointments survive it —
|
|
99
82
|
* but the paths recorded beside them (#887) would still name where the folders
|
|
@@ -101,8 +84,8 @@ const rebasePath = (
|
|
|
101
84
|
* names a path the user has not seen since the rename.
|
|
102
85
|
*
|
|
103
86
|
* The renamed folder is matched by id; its descendants are matched by the path
|
|
104
|
-
* each label already holds, which is the path their rows carried until
|
|
105
|
-
* rename rewrote them.
|
|
87
|
+
* each label already holds, which is the path their rows carried until the
|
|
88
|
+
* rename intent rewrote them.
|
|
106
89
|
*/
|
|
107
90
|
const refreshAppointmentLabels = async (
|
|
108
91
|
accountSetting: Pick<IAccountSettingRepository, "get" | "upsert">,
|
|
@@ -122,7 +105,7 @@ const refreshAppointmentLabels = async (
|
|
|
122
105
|
? renamed.newPath
|
|
123
106
|
: appointment.lastKnownPath === undefined
|
|
124
107
|
? undefined
|
|
125
|
-
:
|
|
108
|
+
: rebaseMailboxPath(
|
|
126
109
|
appointment.lastKnownPath,
|
|
127
110
|
renamed.oldPath,
|
|
128
111
|
renamed.newPath,
|
|
@@ -144,8 +127,8 @@ const refreshAppointmentLabels = async (
|
|
|
144
127
|
* Apply a mailbox PATCH body: override changes first (mute flag + display-name/
|
|
145
128
|
* role overrides — written to per-mailbox AccountSetting rows, no IMAP
|
|
146
129
|
* machinery), then rename — which triggers the IMAP rename machinery
|
|
147
|
-
* (
|
|
148
|
-
* present. An override-only PATCH therefore never calls
|
|
130
|
+
* (the recorded subtree intent + MAILBOX_RENAME event) — only when `fullPath`
|
|
131
|
+
* is present. An override-only PATCH therefore never calls
|
|
149
132
|
* `mailboxQueue.renameMailbox`.
|
|
150
133
|
*/
|
|
151
134
|
export const applyMailboxPatch = async (
|
|
@@ -160,8 +143,8 @@ export const applyMailboxPatch = async (
|
|
|
160
143
|
// --- Override settings (mute flag + display-name/role overrides) ---
|
|
161
144
|
// Written to per-mailbox AccountSetting rows (RFC 032) with the same
|
|
162
145
|
// null→remove semantics as UpdateAddressFlagsInput. Applied before (and
|
|
163
|
-
// independent of) any rename so an override-only PATCH never touches
|
|
164
|
-
//
|
|
146
|
+
// independent of) any rename so an override-only PATCH never touches the
|
|
147
|
+
// row's mutation state.
|
|
165
148
|
const changes = pickMailboxOverrideChanges(body);
|
|
166
149
|
if (Object.keys(changes).length > 0) {
|
|
167
150
|
await applyMailboxOverrideChanges(
|
|
@@ -268,6 +251,11 @@ const toMailboxResponse = (
|
|
|
268
251
|
highWaterMarkUid: mailbox.highWaterMarkUid,
|
|
269
252
|
lastMessageSyncAt: mailbox.lastMessageSyncAt,
|
|
270
253
|
syncStatus: mailbox.syncStatus,
|
|
254
|
+
// The row is the only thing that knows what a rename is aiming at, and
|
|
255
|
+
// `fullPath` stays the confirmed one throughout (D2), so without this a
|
|
256
|
+
// client cannot tell a create in flight from a rename in flight, name the
|
|
257
|
+
// target of a failed rename, or offer the right retry.
|
|
258
|
+
pendingPath: mailbox.pendingPath,
|
|
271
259
|
muted: overrides.muted,
|
|
272
260
|
displayNameOverride: overrides.displayNameOverride,
|
|
273
261
|
createdAt: mailbox.createdAt,
|