@vtex/faststore-plugin-buyer-portal 2.0.31 → 2.0.33
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/package.json
CHANGED
|
@@ -27,7 +27,9 @@ export const tokenizeCreditCardService = async ({
|
|
|
27
27
|
complement: creditCard.address.streetAddress2,
|
|
28
28
|
coutry: creditCard.address.countryCode,
|
|
29
29
|
neighborhood: creditCard.address.neighborhood ?? "",
|
|
30
|
-
geoCoordinates: creditCard.address.geoCoordinates
|
|
30
|
+
geoCoordinates: creditCard.address.geoCoordinates
|
|
31
|
+
? creditCard.address.geoCoordinates.split(",")
|
|
32
|
+
: [],
|
|
31
33
|
postalCode: creditCard.address.zip,
|
|
32
34
|
number: creditCard.address.streetNumber ?? "",
|
|
33
35
|
receiverName: "NOT EMPTY",
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { getApiUrl } from "../utils/api";
|
|
2
|
+
import { CURRENT_VERSION } from "../utils/constants";
|
|
1
3
|
import {
|
|
2
4
|
getAuthFromCookie,
|
|
3
5
|
getCookieWithoutSessionObjects,
|
|
4
6
|
} from "../utils/cookie";
|
|
5
7
|
import { toQueryParams } from "../utils/toQueryParams";
|
|
6
8
|
|
|
9
|
+
const BUYER_PORTAL_CLIENT_HEADER = "x-buyer-portal-client";
|
|
10
|
+
const BUYER_PORTAL_CLIENT = `organization-account/${CURRENT_VERSION}`;
|
|
11
|
+
|
|
7
12
|
interface RequestConfig<Input = unknown> {
|
|
8
13
|
url: string;
|
|
9
14
|
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
@@ -48,8 +53,13 @@ export class ClientError extends Error {
|
|
|
48
53
|
class Client {
|
|
49
54
|
private baseURL: string;
|
|
50
55
|
|
|
56
|
+
// Other hosts (saved cards, tokenization, postal code) would have to allow
|
|
57
|
+
// the header in their CORS preflight.
|
|
58
|
+
private isBffClient: boolean;
|
|
59
|
+
|
|
51
60
|
constructor(baseURL = "") {
|
|
52
61
|
this.baseURL = baseURL;
|
|
62
|
+
this.isBffClient = baseURL.startsWith(getApiUrl());
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
private createClientError(
|
|
@@ -86,11 +96,20 @@ class Client {
|
|
|
86
96
|
cache = "no-cache",
|
|
87
97
|
componentName,
|
|
88
98
|
}: RequestConfig<Input>): Promise<Return> {
|
|
99
|
+
// fetch joins names that differ only in case into one comma-separated
|
|
100
|
+
// value, which the BFF rejects.
|
|
101
|
+
const callerSetsClientHeader = Object.keys(headers).some(
|
|
102
|
+
(name) => name.toLowerCase() === BUYER_PORTAL_CLIENT_HEADER
|
|
103
|
+
);
|
|
104
|
+
|
|
89
105
|
const config: RequestInit = {
|
|
90
106
|
method,
|
|
91
107
|
credentials: "include",
|
|
92
108
|
headers: {
|
|
93
109
|
...(ignoreContentType ? {} : { "Content-Type": "application/json" }),
|
|
110
|
+
...(this.isBffClient && !callerSetsClientHeader
|
|
111
|
+
? { [BUYER_PORTAL_CLIENT_HEADER]: BUYER_PORTAL_CLIENT }
|
|
112
|
+
: {}),
|
|
94
113
|
...(headers.Cookie
|
|
95
114
|
? getCookieWithoutSessionObjects(headers.Cookie ?? "")
|
|
96
115
|
: {}),
|
|
@@ -7,8 +7,18 @@ vi.mock("discovery.config", () => ({
|
|
|
7
7
|
},
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
+
import { getApiUrl } from "../../utils/api";
|
|
11
|
+
import { CURRENT_VERSION } from "../../utils/constants";
|
|
10
12
|
import { Client, ClientError } from "../Client";
|
|
11
13
|
|
|
14
|
+
const CLIENT_HEADER = "x-buyer-portal-client";
|
|
15
|
+
|
|
16
|
+
function sentHeaders(fetchMock: ReturnType<typeof makeFetchMock>) {
|
|
17
|
+
const [, init] = fetchMock.mock.calls[0] as [string, RequestInit];
|
|
18
|
+
|
|
19
|
+
return init.headers as Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
function makeFetchMock(
|
|
13
23
|
body: unknown,
|
|
14
24
|
status = 200,
|
|
@@ -65,4 +75,63 @@ describe("Client", () => {
|
|
|
65
75
|
await expect(client.get("resource")).resolves.toEqual({ ok: true });
|
|
66
76
|
});
|
|
67
77
|
});
|
|
78
|
+
|
|
79
|
+
describe("x-buyer-portal-client", () => {
|
|
80
|
+
it("identifies the plugin on BFF requests", async () => {
|
|
81
|
+
const fetchMock = makeFetchMock({ ok: true });
|
|
82
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
83
|
+
|
|
84
|
+
await new Client(getApiUrl()).get("units/unit-1/summary");
|
|
85
|
+
|
|
86
|
+
expect(sentHeaders(fetchMock)).toMatchObject({
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
[CLIENT_HEADER]: `organization-account/${CURRENT_VERSION}`,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("sends it next to the cookie and auth headers on server-side requests", async () => {
|
|
93
|
+
const fetchMock = makeFetchMock({ ok: true });
|
|
94
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
95
|
+
|
|
96
|
+
await new Client(getApiUrl()).get("granted", {
|
|
97
|
+
headers: {
|
|
98
|
+
Cookie: "VtexIdclientAutCookie_test-store=token-value;other=1",
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(sentHeaders(fetchMock)).toMatchObject({
|
|
103
|
+
[CLIENT_HEADER]: `organization-account/${CURRENT_VERSION}`,
|
|
104
|
+
"VtexIdclientAutCookie_test-store": "token-value",
|
|
105
|
+
Cookie: "VtexIdclientAutCookie_test-store=token-value;other=1",
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it.each(["", "https://test.vtex.com/api/", "https://api.example.com/"])(
|
|
110
|
+
"is not sent to base URL %j",
|
|
111
|
+
async (baseURL) => {
|
|
112
|
+
const fetchMock = makeFetchMock({ ok: true });
|
|
113
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
114
|
+
|
|
115
|
+
await new Client(baseURL).get("resource");
|
|
116
|
+
|
|
117
|
+
expect(sentHeaders(fetchMock)).not.toHaveProperty(CLIENT_HEADER);
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
it.each([CLIENT_HEADER, "X-Buyer-Portal-Client"])(
|
|
122
|
+
"lets a header passed by the caller as %s win",
|
|
123
|
+
async (name) => {
|
|
124
|
+
const fetchMock = makeFetchMock({ ok: true });
|
|
125
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
126
|
+
|
|
127
|
+
await new Client(getApiUrl()).get("resource", {
|
|
128
|
+
headers: { [name]: "organization-account" },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(new Headers(sentHeaders(fetchMock)).get(CLIENT_HEADER)).toBe(
|
|
132
|
+
"organization-account"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
});
|
|
68
137
|
});
|