@faststore/core 4.3.0-dev.6 → 4.3.0-dev.8
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 +271 -30
- 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/sdk/account/useSetPassword.ts +82 -72
- 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/sdk/account/useSetPassword.test.ts +192 -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.7 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.7 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.7 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.7 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/
|
|
9
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/
|
|
8
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 18[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 76[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,15 +14,248 @@
|
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
18
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
19
|
+
|
|
20
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
21
|
+
|
|
22
|
+
act(() => {
|
|
23
|
+
/* fire events that update state */
|
|
24
|
+
});
|
|
25
|
+
/* assert on the output */
|
|
26
|
+
|
|
27
|
+
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
|
|
28
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
29
|
+
Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
30
|
+
|
|
31
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
32
|
+
|
|
33
|
+
act(() => {
|
|
34
|
+
/* fire events that update state */
|
|
35
|
+
});
|
|
36
|
+
/* assert on the output */
|
|
37
|
+
|
|
38
|
+
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
|
|
39
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
40
|
+
|
|
41
|
+
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
42
|
+
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
43
|
+
|
|
44
|
+
When testing, code that causes React state updates should be wrapped into act(...):
|
|
45
|
+
|
|
46
|
+
act(() => {
|
|
47
|
+
/* fire events that update state */
|
|
48
|
+
});
|
|
49
|
+
/* assert on the output */
|
|
50
|
+
|
|
51
|
+
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
|
|
52
|
+
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
53
|
+
|
|
54
|
+
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 14[2mms[22m[39m
|
|
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 1695[2mms[22m[39m
|
|
248
|
+
[33m[2m✓[22m[39m renders the password protection form [33m 805[2mms[22m[39m
|
|
249
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 17[2mms[22m[39m
|
|
250
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 125[2mms[22m[39m
|
|
251
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 117[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 36[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 28[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 856[2mms[22m[39m
|
|
255
|
+
[33m[2m✓[22m[39m returns 405 for non-POST requests [33m 613[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
|
|
|
25
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 55[2mms[22m[39m
|
|
26
259
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx[2m > [22m[2mSearchInput (OES integration)[2m > [22m[2mrenders without crashing
|
|
27
260
|
[22m[39mWarning: React does not recognize the `visibleDropdown` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `visibledropdown` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
|
|
28
261
|
at div
|
|
@@ -83,12 +316,17 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
83
316
|
at Suspense
|
|
84
317
|
at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
|
|
85
318
|
|
|
86
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[
|
|
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/
|
|
90
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m
|
|
91
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
319
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 242[2mms[22m[39m
|
|
320
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/useBindingSelector.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[32m 25[2mms[22m[39m
|
|
321
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 185[2mms[22m[39m
|
|
322
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 53[2mms[22m[39m
|
|
323
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m 148[2mms[22m[39m
|
|
324
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
325
|
+
[90mstderr[2m | test/sdk/account/useSetPassword.test.ts[2m > [22m[2museSetPassword[2m > [22m[2mmaps wrongcredentials error responses to the existing message
|
|
326
|
+
[22m[39mSet password request failed: Bad Request
|
|
327
|
+
|
|
328
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 113[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 84[2mms[22m[39m
|
|
92
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
|
|
93
331
|
[22m[39mGraphql execution returned with error: [
|
|
94
332
|
{
|
|
@@ -135,26 +373,29 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
135
373
|
{ message: [32m'bad'[39m, status: [33m400[39m, type: [32m'BadRequestError'[39m }
|
|
136
374
|
]
|
|
137
375
|
|
|
138
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
139
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
140
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
141
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
376
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 24[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 49[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 48[2mms[22m[39m
|
|
379
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
380
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 63[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 31[2mms[22m[39m
|
|
142
382
|
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
143
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/
|
|
383
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 1124[2mms[22m[39m
|
|
384
|
+
[33m[2m✓[22m[39m should handle options and execute [33m 599[2mms[22m[39m
|
|
385
|
+
[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
|
|
386
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
144
387
|
[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
|
|
145
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 990[2mms[22m[39m
|
|
146
|
-
[33m[2m✓[22m[39m should handle options and execute [33m 520[2mms[22m[39m
|
|
147
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
148
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
149
388
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
150
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
|
|
390
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
151
391
|
[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
|
|
152
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
153
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
392
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
393
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
394
|
+
[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
|
|
154
395
|
[32m✓[39m [30m[43m node [49m[39m test/components/auth/ProfileChallenge.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 26[2mms[22m[39m
|
|
155
396
|
|
|
156
|
-
[2m Test Files [22m [1m[
|
|
157
|
-
[2m Tests [22m [1m[
|
|
158
|
-
[2m Start at [22m
|
|
159
|
-
[2m Duration [22m
|
|
397
|
+
[2m Test Files [22m [1m[32m37 passed[39m[22m[90m (37)[39m
|
|
398
|
+
[2m Tests [22m [1m[32m360 passed[39m[22m[90m (360)[39m
|
|
399
|
+
[2m Start at [22m 21:17:04
|
|
400
|
+
[2m Duration [22m 24.45s[2m (transform 6.16s, setup 0ms, collect 17.83s, tests 5.36s, environment 32.81s, prepare 1.08s)[22m
|
|
160
401
|
|
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-dev.8](https://github.com/vtex/faststore/compare/v4.3.0-dev.7...v4.3.0-dev.8) (2026-06-17)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- Password Protection (v4) ([#3276](https://github.com/vtex/faststore/issues/3276)) ([575f162](https://github.com/vtex/faststore/commit/575f162f6ec6fda9d3134ab61f673a897dcc2f56))
|
|
11
|
+
|
|
12
|
+
# [4.3.0-dev.7](https://github.com/vtex/faststore/compare/v4.3.0-dev.6...v4.3.0-dev.7) (2026-06-17)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- **core:** use authenticator route for setpassword ([#3380](https://github.com/vtex/faststore/issues/3380)) ([a155269](https://github.com/vtex/faststore/commit/a155269678d8a0584a98008b1384bf146f6da1cb))
|
|
17
|
+
|
|
6
18
|
# [4.3.0-dev.6](https://github.com/vtex/faststore/compare/v4.3.0-dev.5...v4.3.0-dev.6) (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-dev.
|
|
3
|
+
"version": "4.3.0-dev.8",
|
|
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-dev.
|
|
74
|
-
"@faststore/
|
|
75
|
-
"@faststore/sdk": "4.3.0-dev.
|
|
76
|
-
"@faststore/ui": "4.3.0-dev.
|
|
77
|
-
"@faststore/
|
|
74
|
+
"@faststore/api": "4.3.0-dev.8",
|
|
75
|
+
"@faststore/diagnostics": "4.3.0-dev.8",
|
|
76
|
+
"@faststore/sdk": "4.3.0-dev.8",
|
|
77
|
+
"@faststore/ui": "4.3.0-dev.8",
|
|
78
|
+
"@faststore/lighthouse": "4.3.0-dev.8"
|
|
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
|
+
}
|