@remit/backend 2.7.0 → 2.7.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.
|
@@ -52,6 +52,8 @@ type ThreadSearch = {
|
|
|
52
52
|
starred?: boolean;
|
|
53
53
|
attachments?: boolean;
|
|
54
54
|
category?: MessageCategory[];
|
|
55
|
+
senderTrust?: SenderTrust[];
|
|
56
|
+
dkimMismatch?: boolean;
|
|
55
57
|
};
|
|
56
58
|
/**
|
|
57
59
|
* Minimal client surface `executeThreadSearch` needs. Declared structurally
|
|
@@ -84,21 +86,12 @@ export type ThreadSearchParams = {
|
|
|
84
86
|
limit?: number;
|
|
85
87
|
};
|
|
86
88
|
/**
|
|
87
|
-
* Run a per-mailbox thread search: select the index/window read
|
|
88
|
-
* count
|
|
89
|
-
*
|
|
89
|
+
* Run a per-mailbox thread search: select the index/window read and optionally
|
|
90
|
+
* count. The `results` toggle omits `items` (count-only) and `count` adds the
|
|
91
|
+
* match count.
|
|
90
92
|
*
|
|
91
93
|
* `count` names the whole match, never the page: a page size bounds the rows a
|
|
92
94
|
* response carries and has no bearing on how many messages match (#509).
|
|
93
|
-
*
|
|
94
|
-
* An off-row criterion is the one shape that has no such number. `senderTrust`
|
|
95
|
-
* and `dkimMismatch` are resolved by enriching a window, so counting them means
|
|
96
|
-
* enriching every candidate row in the mailbox. `count` is therefore absent
|
|
97
|
-
* (#305) — a page's post-filter length labelled `count` is a page length
|
|
98
|
-
* presented as a total, which is the defect the field exists to avoid. Absence
|
|
99
|
-
* is the same answer the response already gives for a count nobody asked for,
|
|
100
|
-
* so no caller needs a second shape to read it. A count-only request under an
|
|
101
|
-
* off-row criterion therefore reads nothing at all.
|
|
102
95
|
*/
|
|
103
96
|
export declare const executeThreadSearch: (client: ThreadSearchClient, accountConfigId: string, mailboxId: string, params: ThreadSearchParams) => Promise<ThreadSearchResponse>;
|
|
104
97
|
/**
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { NotFoundError } from "@remit/data-ports/errors";
|
|
2
2
|
import { isValidMessageId } from "@remit/data-ports/id";
|
|
3
3
|
import { enrichThreadRows, } from "../derive/enrichThreadRows.js";
|
|
4
|
-
import { filterByOffRowCriteria, hasOffRowCriteria, } from "../derive/filterThreadCriteria.js";
|
|
5
4
|
const DEFAULT_THREADS_PAGE_SIZE = 50;
|
|
6
5
|
// Project to fields used by ListThreadsResponse — keep in sync with handler mapping.
|
|
7
6
|
// Includes ThreadMessage table key fields (accountConfigId, threadMessageId) and
|
|
@@ -63,21 +62,12 @@ const toArray = (value) => {
|
|
|
63
62
|
return Array.isArray(value) ? value : [value];
|
|
64
63
|
};
|
|
65
64
|
/**
|
|
66
|
-
* Run a per-mailbox thread search: select the index/window read
|
|
67
|
-
* count
|
|
68
|
-
*
|
|
65
|
+
* Run a per-mailbox thread search: select the index/window read and optionally
|
|
66
|
+
* count. The `results` toggle omits `items` (count-only) and `count` adds the
|
|
67
|
+
* match count.
|
|
69
68
|
*
|
|
70
69
|
* `count` names the whole match, never the page: a page size bounds the rows a
|
|
71
70
|
* response carries and has no bearing on how many messages match (#509).
|
|
72
|
-
*
|
|
73
|
-
* An off-row criterion is the one shape that has no such number. `senderTrust`
|
|
74
|
-
* and `dkimMismatch` are resolved by enriching a window, so counting them means
|
|
75
|
-
* enriching every candidate row in the mailbox. `count` is therefore absent
|
|
76
|
-
* (#305) — a page's post-filter length labelled `count` is a page length
|
|
77
|
-
* presented as a total, which is the defect the field exists to avoid. Absence
|
|
78
|
-
* is the same answer the response already gives for a count nobody asked for,
|
|
79
|
-
* so no caller needs a second shape to read it. A count-only request under an
|
|
80
|
-
* off-row criterion therefore reads nothing at all.
|
|
81
71
|
*/
|
|
82
72
|
export const executeThreadSearch = async (client, accountConfigId, mailboxId, params) => {
|
|
83
73
|
const search = {
|
|
@@ -88,8 +78,6 @@ export const executeThreadSearch = async (client, accountConfigId, mailboxId, pa
|
|
|
88
78
|
starred: params.starred,
|
|
89
79
|
attachments: params.attachments,
|
|
90
80
|
category: params.category,
|
|
91
|
-
};
|
|
92
|
-
const offRow = {
|
|
93
81
|
senderTrust: params.senderTrust,
|
|
94
82
|
dkimMismatch: params.dkimMismatch,
|
|
95
83
|
};
|
|
@@ -100,16 +88,6 @@ export const executeThreadSearch = async (client, accountConfigId, mailboxId, pa
|
|
|
100
88
|
order: params.order,
|
|
101
89
|
limit: params.limit,
|
|
102
90
|
});
|
|
103
|
-
if (hasOffRowCriteria(offRow)) {
|
|
104
|
-
if (!wantResults)
|
|
105
|
-
return {};
|
|
106
|
-
const window = await client.threadMessage.searchByMailboxWindow(accountConfigId, mailboxId, search, options);
|
|
107
|
-
const enriched = await enrichThreadRows(window.items, client, accountConfigId);
|
|
108
|
-
return {
|
|
109
|
-
items: filterByOffRowCriteria(enriched, offRow),
|
|
110
|
-
continuationToken: window.continuationToken,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
91
|
const response = {};
|
|
114
92
|
if (wantResults) {
|
|
115
93
|
const window = await client.threadMessage.searchByMailboxWindow(accountConfigId, mailboxId, search, options);
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { SenderTrust, ThreadMessageResponse } from "@remit/api-openapi-types";
|
|
2
|
-
/**
|
|
3
|
-
* Off-row search criteria — fields that live on the underlying Message/Address,
|
|
4
|
-
* not on the ThreadMessage row. They are resolved by enriching the windowed
|
|
5
|
-
* rows (see enrichThreadRows) and filtering in app code, because no index or
|
|
6
|
-
* FilterExpression can serve them.
|
|
7
|
-
*
|
|
8
|
-
* `senderTrust` derives from AddressItem.flags and `dkimMismatch` from
|
|
9
|
-
* MessageItem.authenticity. `category` is not one of these: it is denormalized
|
|
10
|
-
* onto the ThreadMessage row and filtered in SQL, inside the window.
|
|
11
|
-
*/
|
|
12
|
-
export interface OffRowCriteria {
|
|
13
|
-
senderTrust?: SenderTrust[];
|
|
14
|
-
dkimMismatch?: boolean;
|
|
15
|
-
}
|
|
16
|
-
export declare const hasOffRowCriteria: (criteria: OffRowCriteria) => boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Filter enriched rows by the off-row criteria. Each active criterion is an
|
|
19
|
-
* any-of set (AND across criteria, OR within a set). A row with no
|
|
20
|
-
* `authenticity` signal never matches a `dkimMismatch` filter (absence means no
|
|
21
|
-
* signal, not a verdict).
|
|
22
|
-
*/
|
|
23
|
-
export declare const filterByOffRowCriteria: (rows: ThreadMessageResponse[], criteria: OffRowCriteria) => ThreadMessageResponse[];
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export const hasOffRowCriteria = (criteria) => Boolean(criteria.senderTrust?.length) || criteria.dkimMismatch !== undefined;
|
|
2
|
-
/**
|
|
3
|
-
* Filter enriched rows by the off-row criteria. Each active criterion is an
|
|
4
|
-
* any-of set (AND across criteria, OR within a set). A row with no
|
|
5
|
-
* `authenticity` signal never matches a `dkimMismatch` filter (absence means no
|
|
6
|
-
* signal, not a verdict).
|
|
7
|
-
*/
|
|
8
|
-
export const filterByOffRowCriteria = (rows, criteria) => {
|
|
9
|
-
if (!hasOffRowCriteria(criteria))
|
|
10
|
-
return rows;
|
|
11
|
-
const trustSet = criteria.senderTrust?.length
|
|
12
|
-
? new Set(criteria.senderTrust)
|
|
13
|
-
: undefined;
|
|
14
|
-
const { dkimMismatch } = criteria;
|
|
15
|
-
return rows.filter((row) => {
|
|
16
|
-
if (trustSet && !trustSet.has(row.senderTrust))
|
|
17
|
-
return false;
|
|
18
|
-
if (dkimMismatch !== undefined &&
|
|
19
|
-
row.authenticity?.dkimMismatch !== dkimMismatch) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return true;
|
|
23
|
-
});
|
|
24
|
-
};
|