@faststore/core 4.3.0-dev.7 → 4.3.0
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/.turbo/turbo-generate.log +3 -3
- package/.turbo/turbo-test.log +267 -32
- package/CHANGELOG.md +12 -0
- package/package.json +9 -6
- package/src/pages/api/fs/password-protection/unlock.ts +123 -0
- package/src/pages/password-protection/index.tsx +93 -0
- package/src/pages/password-protection/password-protection.module.scss +43 -0
- package/src/proxy.ts +47 -2
- package/src/server/password-protection/webops-api.ts +38 -0
- package/src/server/password-protection-service.ts +283 -0
- package/src/utils/unlockResponse.ts +25 -0
- package/test/pages/api/unlock.test.ts +277 -0
- package/test/pages/password-protection.browser.test.tsx +201 -0
- package/test/proxy.test.ts +99 -0
- package/test/server/password-protection-service.test.ts +624 -0
- package/test/server/webops-api.test.ts +92 -0
- package/test/utils/unlockResponse.test.ts +57 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.3.0-dev.
|
|
2
|
+
> @faststore/core@4.3.0-dev.8 generate /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> pnpm run gen-types && pnpm run cache-graphql
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @faststore/core@4.3.0-dev.
|
|
6
|
+
> @faststore/core@4.3.0-dev.8 gen-types /home/runner/work/faststore/faststore/packages/core
|
|
7
7
|
> node ../cli/bin/run generate-types .
|
|
8
8
|
|
|
9
9
|
[33m[STARTED][39m Parse Configuration
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
[32m[COMPLETED][39m Generate to /home/runner/work/faststore/faststore/packages/core/@generated/
|
|
20
20
|
[32m[COMPLETED][39m Generate outputs
|
|
21
21
|
|
|
22
|
-
> @faststore/core@4.3.0-dev.
|
|
22
|
+
> @faststore/core@4.3.0-dev.8 cache-graphql /home/runner/work/faststore/faststore/packages/core
|
|
23
23
|
> node ../cli/bin/run cache-graphql --config=./discovery.config.default.js --queries=./@generated/persisted-documents.json
|
|
24
24
|
|
|
25
25
|
[Info] - Config file location: /home/runner/work/faststore/faststore/packages/core/discovery.config.default.js
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.3.0-dev.
|
|
2
|
+
> @faststore/core@4.3.0-dev.8 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[46m RUN [49m[22m [36mv4.0.7 [39m[90m/home/runner/work/faststore/faststore/packages/core[39m
|
|
7
7
|
|
|
8
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
9
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/installLocaleCorrector.browser.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
8
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 60[2mms[22m[39m
|
|
9
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/installLocaleCorrector.browser.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 93[2mms[22m[39m
|
|
10
10
|
[90mstderr[2m | test/sdk/localization/store-url.browser.test.ts
|
|
11
11
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
12
12
|
at validateCart [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/index.ts:119:27[90m)[39m
|
|
@@ -14,11 +14,245 @@
|
|
|
14
14
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:353:23)
|
|
15
15
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
16
16
|
|
|
17
|
+
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
18
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
19
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
20
|
+
|
|
21
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
22
|
+
|
|
23
|
+
act(() => {
|
|
24
|
+
/* fire events that update state */
|
|
25
|
+
});
|
|
26
|
+
/* assert on the output */
|
|
27
|
+
|
|
28
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
29
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
30
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
31
|
+
|
|
32
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
33
|
+
|
|
34
|
+
act(() => {
|
|
35
|
+
/* fire events that update state */
|
|
36
|
+
});
|
|
37
|
+
/* assert on the output */
|
|
38
|
+
|
|
39
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
40
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
41
|
+
|
|
42
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
43
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
44
|
+
|
|
45
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
46
|
+
|
|
47
|
+
act(() => {
|
|
48
|
+
/* fire events that update state */
|
|
49
|
+
});
|
|
50
|
+
/* assert on the output */
|
|
51
|
+
|
|
52
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
53
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
54
|
+
|
|
55
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mdefaults returnTo to root and shows API validation errors
|
|
56
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
57
|
+
|
|
58
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
59
|
+
|
|
60
|
+
act(() => {
|
|
61
|
+
/* fire events that update state */
|
|
62
|
+
});
|
|
63
|
+
/* assert on the output */
|
|
64
|
+
|
|
65
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
66
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
67
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
68
|
+
|
|
69
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
70
|
+
|
|
71
|
+
act(() => {
|
|
72
|
+
/* fire events that update state */
|
|
73
|
+
});
|
|
74
|
+
/* assert on the output */
|
|
75
|
+
|
|
76
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
77
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
78
|
+
|
|
79
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mdefaults returnTo to root and shows API validation errors
|
|
80
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
81
|
+
|
|
82
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
83
|
+
|
|
84
|
+
act(() => {
|
|
85
|
+
/* fire events that update state */
|
|
86
|
+
});
|
|
87
|
+
/* assert on the output */
|
|
88
|
+
|
|
89
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
90
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
91
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
92
|
+
|
|
93
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
94
|
+
|
|
95
|
+
act(() => {
|
|
96
|
+
/* fire events that update state */
|
|
97
|
+
});
|
|
98
|
+
/* assert on the output */
|
|
99
|
+
|
|
100
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
101
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
102
|
+
|
|
103
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2muses the fallback invalid-password message when API omits an error
|
|
104
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
105
|
+
|
|
106
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
107
|
+
|
|
108
|
+
act(() => {
|
|
109
|
+
/* fire events that update state */
|
|
110
|
+
});
|
|
111
|
+
/* assert on the output */
|
|
112
|
+
|
|
113
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
114
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
115
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
116
|
+
|
|
117
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
118
|
+
|
|
119
|
+
act(() => {
|
|
120
|
+
/* fire events that update state */
|
|
121
|
+
});
|
|
122
|
+
/* assert on the output */
|
|
123
|
+
|
|
124
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
125
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
126
|
+
|
|
127
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2muses the fallback invalid-password message when API omits an error
|
|
128
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
129
|
+
|
|
130
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
131
|
+
|
|
132
|
+
act(() => {
|
|
133
|
+
/* fire events that update state */
|
|
134
|
+
});
|
|
135
|
+
/* assert on the output */
|
|
136
|
+
|
|
137
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
138
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
139
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
140
|
+
|
|
141
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
142
|
+
|
|
143
|
+
act(() => {
|
|
144
|
+
/* fire events that update state */
|
|
145
|
+
});
|
|
146
|
+
/* assert on the output */
|
|
147
|
+
|
|
148
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
149
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
150
|
+
|
|
151
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mshows service unavailable when the response is not a login payload
|
|
152
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
153
|
+
|
|
154
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
155
|
+
|
|
156
|
+
act(() => {
|
|
157
|
+
/* fire events that update state */
|
|
158
|
+
});
|
|
159
|
+
/* assert on the output */
|
|
160
|
+
|
|
161
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
162
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
163
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
164
|
+
|
|
165
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
166
|
+
|
|
167
|
+
act(() => {
|
|
168
|
+
/* fire events that update state */
|
|
169
|
+
});
|
|
170
|
+
/* assert on the output */
|
|
171
|
+
|
|
172
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
173
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
174
|
+
|
|
175
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mshows service unavailable when the response is not a login payload
|
|
176
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
177
|
+
|
|
178
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
179
|
+
|
|
180
|
+
act(() => {
|
|
181
|
+
/* fire events that update state */
|
|
182
|
+
});
|
|
183
|
+
/* assert on the output */
|
|
184
|
+
|
|
185
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
186
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
187
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
188
|
+
|
|
189
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
190
|
+
|
|
191
|
+
act(() => {
|
|
192
|
+
/* fire events that update state */
|
|
193
|
+
});
|
|
194
|
+
/* assert on the output */
|
|
195
|
+
|
|
196
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
197
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
198
|
+
|
|
199
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mshows service unavailable when the login request fails
|
|
200
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
201
|
+
|
|
202
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
203
|
+
|
|
204
|
+
act(() => {
|
|
205
|
+
/* fire events that update state */
|
|
206
|
+
});
|
|
207
|
+
/* assert on the output */
|
|
208
|
+
|
|
209
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
210
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
211
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
212
|
+
|
|
213
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
214
|
+
|
|
215
|
+
act(() => {
|
|
216
|
+
/* fire events that update state */
|
|
217
|
+
});
|
|
218
|
+
/* assert on the output */
|
|
219
|
+
|
|
220
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
221
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
222
|
+
|
|
223
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mshows service unavailable when the login request fails
|
|
224
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
225
|
+
|
|
226
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
227
|
+
|
|
228
|
+
act(() => {
|
|
229
|
+
/* fire events that update state */
|
|
230
|
+
});
|
|
231
|
+
/* assert on the output */
|
|
232
|
+
|
|
233
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
234
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
235
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
236
|
+
|
|
237
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
238
|
+
|
|
239
|
+
act(() => {
|
|
240
|
+
/* fire events that update state */
|
|
241
|
+
});
|
|
242
|
+
/* assert on the output */
|
|
243
|
+
|
|
244
|
+
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
245
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
246
|
+
|
|
247
|
+
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 1352[2mms[22m[39m
|
|
248
|
+
[33m[2m✓[22m[39m renders the password protection form [33m 644[2mms[22m[39m
|
|
249
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 84[2mms[22m[39m
|
|
17
250
|
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
18
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
19
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/match-url.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
20
|
-
[32m✓[39m [30m[
|
|
21
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
251
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 93[2mms[22m[39m
|
|
252
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/match-url.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
253
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/bindingSelector.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
254
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/unlock.test.ts [2m([22m[2m15 tests[22m[2m)[22m[33m 749[2mms[22m[39m
|
|
255
|
+
[33m[2m✓[22m[39m returns 405 for non-POST requests [33m 524[2mms[22m[39m
|
|
22
256
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx
|
|
23
257
|
[22m[39mWarning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
|
|
24
258
|
|
|
@@ -82,17 +316,17 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
82
316
|
at Suspense
|
|
83
317
|
at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
|
|
84
318
|
|
|
85
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[
|
|
86
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
87
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
88
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
89
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m
|
|
90
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
319
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 258[2mms[22m[39m
|
|
320
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 44[2mms[22m[39m
|
|
321
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/useBindingSelector.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[32m 33[2mms[22m[39m
|
|
322
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 201[2mms[22m[39m
|
|
323
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m 60[2mms[22m[39m
|
|
324
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
91
325
|
[90mstderr[2m | test/sdk/account/useSetPassword.test.ts[2m > [22m[2museSetPassword[2m > [22m[2mmaps wrongcredentials error responses to the existing message
|
|
92
326
|
[22m[39mSet password request failed: Bad Request
|
|
93
327
|
|
|
94
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
95
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
328
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
329
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 55[2mms[22m[39m
|
|
96
330
|
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql error status propagation[2m > [22m[2mpropagates the upstream 400 from a wrapped BadRequestError instead of 500
|
|
97
331
|
[22m[39mGraphql execution returned with error: [
|
|
98
332
|
{
|
|
@@ -139,27 +373,28 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
139
373
|
{ message: [32m'bad'[39m, status: [33m400[39m, type: [32m'BadRequestError'[39m }
|
|
140
374
|
]
|
|
141
375
|
|
|
142
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
143
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
144
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
145
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
376
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
377
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 42[2mms[22m[39m
|
|
378
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 41[2mms[22m[39m
|
|
379
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
380
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 34[2mms[22m[39m
|
|
381
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/webops-api.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 34[2mms[22m[39m
|
|
146
382
|
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
147
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/content/service.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
151
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/store-url.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
383
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 702[2mms[22m[39m
|
|
384
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/content/service.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
385
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/store-url.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
152
386
|
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
153
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
154
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
387
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
388
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
155
389
|
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
156
390
|
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInput.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
157
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/
|
|
391
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
158
392
|
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
159
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
393
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
394
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/auth/ProfileChallenge.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 25[2mms[22m[39m
|
|
160
395
|
|
|
161
|
-
[2m Test Files [22m [1m[
|
|
162
|
-
[2m Tests [22m [1m[
|
|
163
|
-
[2m Start at [22m
|
|
164
|
-
[2m Duration [22m
|
|
396
|
+
[2m Test Files [22m [1m[32m37 passed[39m[22m[90m (37)[39m
|
|
397
|
+
[2m Tests [22m [1m[32m360 passed[39m[22m[90m (360)[39m
|
|
398
|
+
[2m Start at [22m 23:06:26
|
|
399
|
+
[2m Duration [22m 23.06s[2m (transform 6.34s, setup 0ms, collect 18.08s, tests 4.27s, environment 29.37s, prepare 968ms)[22m
|
|
165
400
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.3.0](https://github.com/vtex/faststore/compare/v4.2.0...v4.3.0) (2026-06-17)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- graduate v4.3.0 ([#3396](https://github.com/vtex/faststore/issues/3396)) ([b489766](https://github.com/vtex/faststore/commit/b4897664c7826dcd59bfde7c3599c93259d4d11f)), closes [#3276](https://github.com/vtex/faststore/issues/3276) [#3334](https://github.com/vtex/faststore/issues/3334) [#3386](https://github.com/vtex/faststore/issues/3386) [#3380](https://github.com/vtex/faststore/issues/3380) [#3394](https://github.com/vtex/faststore/issues/3394) [#3395](https://github.com/vtex/faststore/issues/3395) [#3381](https://github.com/vtex/faststore/issues/3381) [#3379](https://github.com/vtex/faststore/issues/3379) [#3375](https://github.com/vtex/faststore/issues/3375)
|
|
11
|
+
|
|
12
|
+
# [4.3.0-dev.8](https://github.com/vtex/faststore/compare/v4.3.0-dev.7...v4.3.0-dev.8) (2026-06-17)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- Password Protection (v4) ([#3276](https://github.com/vtex/faststore/issues/3276)) ([575f162](https://github.com/vtex/faststore/commit/575f162f6ec6fda9d3134ab61f673a897dcc2f56))
|
|
17
|
+
|
|
6
18
|
# [4.3.0-dev.7](https://github.com/vtex/faststore/compare/v4.3.0-dev.6...v4.3.0-dev.7) (2026-06-17)
|
|
7
19
|
|
|
8
20
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "4.3.0
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"fs-extra": "^10.1.0",
|
|
59
59
|
"idb-keyval": "^5.1.3",
|
|
60
60
|
"isomorphic-unfetch": "^3.1.0",
|
|
61
|
+
"jose": "^6.2.3",
|
|
61
62
|
"lexical": "^0.34.0",
|
|
62
63
|
"next": "^16.2.6",
|
|
63
64
|
"next-seo": "^6.6.0",
|
|
@@ -70,17 +71,19 @@
|
|
|
70
71
|
"style-loader": "^3.3.1",
|
|
71
72
|
"swr": "^2.2.5",
|
|
72
73
|
"use-sync-external-store": "^1.6.0",
|
|
73
|
-
"@faststore/api": "4.3.0
|
|
74
|
-
"@faststore/
|
|
75
|
-
"@faststore/
|
|
76
|
-
"@faststore/
|
|
77
|
-
"@faststore/
|
|
74
|
+
"@faststore/api": "4.3.0",
|
|
75
|
+
"@faststore/lighthouse": "4.3.0",
|
|
76
|
+
"@faststore/diagnostics": "4.3.0",
|
|
77
|
+
"@faststore/sdk": "4.3.0",
|
|
78
|
+
"@faststore/ui": "4.3.0"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@cypress/code-coverage": "^3.12.1",
|
|
81
82
|
"@envelop/testing": "^10",
|
|
82
83
|
"@testing-library/cypress": "^10.0.1",
|
|
84
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
83
85
|
"@testing-library/react": "14.3.1",
|
|
86
|
+
"@testing-library/user-event": "14.5.2",
|
|
84
87
|
"@types/cookie": "^0.6.0",
|
|
85
88
|
"@types/fs-extra": "^9.0.13",
|
|
86
89
|
"@types/node": "20.19.13",
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
|
2
|
+
|
|
3
|
+
import storeConfig from 'discovery.config'
|
|
4
|
+
|
|
5
|
+
import type { UnlockResponse } from 'src/utils/unlockResponse'
|
|
6
|
+
import {
|
|
7
|
+
sessionUrl,
|
|
8
|
+
passwordProtectionTimeouts,
|
|
9
|
+
} from 'src/server/password-protection/webops-api'
|
|
10
|
+
import {
|
|
11
|
+
COOKIE_NAME,
|
|
12
|
+
TOKEN_TTL_SECONDS,
|
|
13
|
+
} from 'src/server/password-protection-service'
|
|
14
|
+
|
|
15
|
+
interface WebOpsSessionPayload {
|
|
16
|
+
valid: boolean
|
|
17
|
+
token?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const isSafeReturnToPath = (value: string): boolean => {
|
|
21
|
+
return value.startsWith('/') && !value.startsWith('//')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isWebOpsSessionPayload = (
|
|
25
|
+
data: unknown
|
|
26
|
+
): data is WebOpsSessionPayload => {
|
|
27
|
+
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const payload = data as Record<string, unknown>
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
typeof payload.valid === 'boolean' &&
|
|
35
|
+
(payload.token === undefined || typeof payload.token === 'string')
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const handler: NextApiHandler<UnlockResponse> = async (
|
|
40
|
+
request: NextApiRequest,
|
|
41
|
+
response: NextApiResponse<UnlockResponse>
|
|
42
|
+
) => {
|
|
43
|
+
if (request.method !== 'POST') {
|
|
44
|
+
response.status(405).end()
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const storeId = storeConfig.api.storeId
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const { password } = request.body ?? {}
|
|
52
|
+
|
|
53
|
+
if (!password || typeof password !== 'string') {
|
|
54
|
+
response.status(400).json({
|
|
55
|
+
success: false,
|
|
56
|
+
error: 'Password is required',
|
|
57
|
+
})
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const webopsResponse = await fetch(sessionUrl(), {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: { 'Content-Type': 'application/json' },
|
|
64
|
+
body: JSON.stringify({ storeId, password }),
|
|
65
|
+
signal: AbortSignal.timeout(passwordProtectionTimeouts.defaultMs),
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
if (!webopsResponse.ok) {
|
|
69
|
+
if (webopsResponse.status === 401 || webopsResponse.status === 403) {
|
|
70
|
+
response.status(401).json({
|
|
71
|
+
success: false,
|
|
72
|
+
error: 'Invalid password',
|
|
73
|
+
})
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
response.status(503).json({
|
|
78
|
+
success: false,
|
|
79
|
+
error: 'Service temporarily unavailable',
|
|
80
|
+
})
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const data: unknown = await webopsResponse.json()
|
|
85
|
+
|
|
86
|
+
if (!isWebOpsSessionPayload(data)) {
|
|
87
|
+
response.status(500).json({
|
|
88
|
+
success: false,
|
|
89
|
+
error: 'Internal server error',
|
|
90
|
+
})
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (data.valid && data.token) {
|
|
95
|
+
const returnTo =
|
|
96
|
+
typeof request.query.returnTo === 'string'
|
|
97
|
+
? request.query.returnTo
|
|
98
|
+
: '/'
|
|
99
|
+
const sanitizedReturnTo = isSafeReturnToPath(returnTo) ? returnTo : '/'
|
|
100
|
+
|
|
101
|
+
response.setHeader('Set-Cookie', [
|
|
102
|
+
`${COOKIE_NAME}=${data.token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=${TOKEN_TTL_SECONDS}`,
|
|
103
|
+
])
|
|
104
|
+
|
|
105
|
+
response.status(200).json({
|
|
106
|
+
success: true,
|
|
107
|
+
redirectUrl: sanitizedReturnTo,
|
|
108
|
+
})
|
|
109
|
+
} else {
|
|
110
|
+
response.status(401).json({
|
|
111
|
+
success: false,
|
|
112
|
+
error: 'Invalid password',
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
response.status(503).json({
|
|
117
|
+
success: false,
|
|
118
|
+
error: 'Service temporarily unavailable',
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default handler
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Button, InputField } from '@faststore/ui'
|
|
2
|
+
import Head from 'next/head'
|
|
3
|
+
import { useRouter } from 'next/router'
|
|
4
|
+
import { type FormEvent, useState } from 'react'
|
|
5
|
+
|
|
6
|
+
import { isUnlockResponse } from '../../utils/unlockResponse'
|
|
7
|
+
import styles from './password-protection.module.scss'
|
|
8
|
+
|
|
9
|
+
export default function PasswordProtectionLogin() {
|
|
10
|
+
const router = useRouter()
|
|
11
|
+
const returnTo =
|
|
12
|
+
typeof router.query.returnTo === 'string' ? router.query.returnTo : '/'
|
|
13
|
+
|
|
14
|
+
const [password, setPassword] = useState('')
|
|
15
|
+
const [error, setError] = useState('')
|
|
16
|
+
const [loading, setLoading] = useState(false)
|
|
17
|
+
|
|
18
|
+
const handleSubmit = async (e: FormEvent) => {
|
|
19
|
+
e.preventDefault()
|
|
20
|
+
setLoading(true)
|
|
21
|
+
setError('')
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(
|
|
25
|
+
'/api/fs/password-protection/unlock',
|
|
26
|
+
globalThis.location.origin
|
|
27
|
+
)
|
|
28
|
+
url.searchParams.set('returnTo', returnTo)
|
|
29
|
+
|
|
30
|
+
const response = await fetch(url.toString(), {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: { 'Content-Type': 'application/json' },
|
|
33
|
+
body: JSON.stringify({ password }),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const data: unknown = await response.json()
|
|
37
|
+
|
|
38
|
+
if (!isUnlockResponse(data)) {
|
|
39
|
+
setError('Service temporarily unavailable')
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (data.success && data.redirectUrl) {
|
|
44
|
+
globalThis.location.href = data.redirectUrl
|
|
45
|
+
} else {
|
|
46
|
+
setError(data.error ?? 'Invalid password')
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
setError('Service temporarily unavailable')
|
|
50
|
+
} finally {
|
|
51
|
+
setLoading(false)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className={styles.fsPasswordProtection}>
|
|
57
|
+
<Head>
|
|
58
|
+
<meta name="robots" content="noindex,nofollow" />
|
|
59
|
+
</Head>
|
|
60
|
+
<div className={styles.page}>
|
|
61
|
+
<h1 className={styles.title}>This store is password protected</h1>
|
|
62
|
+
|
|
63
|
+
<h2 className={styles.subtitle}>
|
|
64
|
+
Enter the password to access the store
|
|
65
|
+
</h2>
|
|
66
|
+
|
|
67
|
+
<form className={styles.form} onSubmit={handleSubmit}>
|
|
68
|
+
<InputField
|
|
69
|
+
id="password-protection-input"
|
|
70
|
+
label="Password"
|
|
71
|
+
type="password"
|
|
72
|
+
value={password}
|
|
73
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
74
|
+
placeholder="Enter password"
|
|
75
|
+
autoComplete="current-password"
|
|
76
|
+
required
|
|
77
|
+
disabled={loading}
|
|
78
|
+
error={error || undefined}
|
|
79
|
+
/>
|
|
80
|
+
<Button
|
|
81
|
+
type="submit"
|
|
82
|
+
variant="primary"
|
|
83
|
+
size="small"
|
|
84
|
+
disabled={loading}
|
|
85
|
+
loading={loading}
|
|
86
|
+
>
|
|
87
|
+
Unlock
|
|
88
|
+
</Button>
|
|
89
|
+
</form>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
93
|
+
}
|