@faststore/core 3.96.2 → 3.96.4-dev.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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +37 -37
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/948.js +2 -2
- package/.next/server/chunks/9563.js +1 -1
- package/.next/server/chunks/9630.js +7 -7
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/api/fs/logout.js +1 -0
- package/.next/server/pages/api/fs/logout.js.nft.json +1 -0
- package/.next/server/pages/api/graphql.js +3 -3
- package/.next/server/pages/en-US/404.html +1 -2
- package/.next/server/pages/en-US/500.html +1 -2
- package/.next/server/pages/en-US/checkout.html +1 -2
- package/.next/server/pages/en-US/login.html +1 -2
- package/.next/server/pages/en-US/s.html +1 -2
- package/.next/server/pages/en-US.html +1 -2
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/chunks/4803.9822f0b7e469b933.js +1 -0
- package/.next/static/chunks/9173-ab3c4d9d8f978c4b.js +1 -0
- package/.next/static/chunks/pages/_app-3898f7fdf2646553.js +1 -0
- package/.next/static/chunks/{webpack-237c97ab0eda7441.js → webpack-5ac0858ff0030797.js} +1 -1
- package/.next/static/{e2njurziU7hHK8M7cTbr- → iASZ3lkWoTXpcEiPm4xkW}/_buildManifest.js +1 -1
- package/.next/trace +139 -138
- package/.turbo/turbo-build.log +24 -23
- package/.turbo/turbo-test.log +9 -7
- package/CHANGELOG.md +32 -0
- package/cms/faststore/pages/cms_content_type__landingpage.jsonc +6 -0
- package/package.json +7 -7
- package/src/components/ThirdPartyScripts/ThirdPartyScripts.tsx +4 -1
- package/src/components/account/MyAccountDrawer/OrganizationDrawer/OrganizationDrawer.tsx +104 -4
- package/src/pages/api/fs/logout.ts +76 -0
- package/src/utils/clearCookies.ts +79 -0
- package/test/utils/clearCookies.test.ts +232 -0
- package/.next/static/chunks/4803.18fbf77cd924d443.js +0 -1
- package/.next/static/chunks/9173-2ed920b87ee6640e.js +0 -1
- package/.next/static/chunks/pages/_app-35b56c71ba4f9a54.js +0 -1
- /package/.next/static/{e2njurziU7hHK8M7cTbr- → iASZ3lkWoTXpcEiPm4xkW}/_ssgManifest.js +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.96.
|
|
2
|
+
> @faststore/core@3.96.3 prebuild /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> na run partytown && na run generate
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @faststore/core@3.96.
|
|
6
|
+
> @faststore/core@3.96.3 partytown /home/runner/work/faststore/faststore/packages/core
|
|
7
7
|
> partytown copylib ./public/~partytown
|
|
8
8
|
|
|
9
9
|
Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
|
|
10
10
|
|
|
11
|
-
> @faststore/core@3.96.
|
|
11
|
+
> @faststore/core@3.96.3 generate /home/runner/work/faststore/faststore/packages/core
|
|
12
12
|
> na run generate:schema && na run generate:codegen && na run format:generated
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
> @faststore/core@3.96.
|
|
15
|
+
> @faststore/core@3.96.3 generate:schema /home/runner/work/faststore/faststore/packages/core
|
|
16
16
|
> tsx src/server/generator/generateGraphQLSchemaFile.ts
|
|
17
17
|
|
|
18
18
|
Schema GraphQL file generated successfully
|
|
19
19
|
|
|
20
|
-
> @faststore/core@3.96.
|
|
20
|
+
> @faststore/core@3.96.3 generate:codegen /home/runner/work/faststore/faststore/packages/core
|
|
21
21
|
> graphql-codegen
|
|
22
22
|
|
|
23
23
|
[STARTED] Parse Configuration
|
|
@@ -37,11 +37,11 @@ Running lifecycle hook "afterStart" scripts...
|
|
|
37
37
|
[CLI] Loading Documents
|
|
38
38
|
[CLI] Generating output
|
|
39
39
|
|
|
40
|
-
> @faststore/core@3.96.
|
|
40
|
+
> @faststore/core@3.96.3 format:generated /home/runner/work/faststore/faststore/packages/core
|
|
41
41
|
> prettier --write "@generated/**/*.{ts,js,tsx,jsx,json}" --loglevel error
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
> @faststore/core@3.96.
|
|
44
|
+
> @faststore/core@3.96.3 build /home/runner/work/faststore/faststore/packages/core
|
|
45
45
|
> next build
|
|
46
46
|
|
|
47
47
|
⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
|
|
@@ -80,8 +80,8 @@ Import trace for requested module:
|
|
|
80
80
|
Collecting page data ...
|
|
81
81
|
Generating static pages (0/6) ...
|
|
82
82
|
|
|
83
83
|
Generating static pages (1/6)
|
|
84
|
-
|
|
85
84
|
Generating static pages (2/6)
|
|
86
85
|
Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Content documentation at https://developers.vtex.com/docs/guides/faststore/dynamic-content-overview for mapping the page and the corresponding data-fetching function.
|
|
86
|
+
|
|
87
87
|
Generating static pages (2/6)
|
|
88
88
|
|
|
89
89
|
Generating static pages (4/6)
|
|
90
90
|
|
|
91
91
|
✓ Generating static pages (6/6)
|
|
92
92
|
Finalizing page optimization ...
|
|
@@ -91,39 +91,40 @@ Route (pages) Size First Load JS
|
|
|
91
91
|
┌ ● / 7.39 kB 147 kB
|
|
92
92
|
├ └ css/02259c549b2179f2.css 3.1 kB
|
|
93
93
|
├ /_app 0 B 108 kB
|
|
94
|
-
├ ● /[...slug] 2.55 kB
|
|
95
|
-
├ ● /[slug]/p 98.1 kB
|
|
94
|
+
├ ● /[...slug] 2.55 kB 158 kB
|
|
95
|
+
├ ● /[slug]/p 98.1 kB 238 kB
|
|
96
96
|
├ └ css/a6a4ebbe01adbbad.css 22.2 kB
|
|
97
|
-
├ ○ /404 1.57 kB
|
|
98
|
-
├ ● /500 1.57 kB
|
|
97
|
+
├ ○ /404 1.57 kB 142 kB
|
|
98
|
+
├ ● /500 1.57 kB 142 kB
|
|
99
|
+
├ λ /api/fs/logout 0 B 108 kB
|
|
99
100
|
├ λ /api/graphql 0 B 108 kB
|
|
100
101
|
├ λ /api/health/live 0 B 108 kB
|
|
101
102
|
├ λ /api/health/ready 0 B 108 kB
|
|
102
103
|
├ λ /api/preview 0 B 108 kB
|
|
103
|
-
├ ● /checkout 749 B
|
|
104
|
-
├ ● /login 1.7 kB
|
|
105
|
-
├ λ /pvt/account 247 B
|
|
104
|
+
├ ● /checkout 749 B 141 kB
|
|
105
|
+
├ ● /login 1.7 kB 142 kB
|
|
106
|
+
├ λ /pvt/account 247 B 109 kB
|
|
106
107
|
├ ● /pvt/account/[...unknown] 287 B 109 kB
|
|
107
|
-
├ λ /pvt/account/403 2.98 kB
|
|
108
|
+
├ λ /pvt/account/403 2.98 kB 143 kB
|
|
108
109
|
├ └ css/0fae3d432331aae9.css 4.68 kB
|
|
109
110
|
├ λ /pvt/account/404 2.18 kB 142 kB
|
|
110
111
|
├ └ css/0fc6b2ff69142c6a.css 4.74 kB
|
|
111
|
-
├ λ /pvt/account/orders 9.78 kB
|
|
112
|
+
├ λ /pvt/account/orders 9.78 kB 150 kB
|
|
112
113
|
├ └ css/40a294d0a24ad01d.css 14.1 kB
|
|
113
|
-
├ λ /pvt/account/orders/[id] 12.1 kB
|
|
114
|
+
├ λ /pvt/account/orders/[id] 12.1 kB 152 kB
|
|
114
115
|
├ └ css/5eecefd2c6deeee4.css 13.3 kB
|
|
115
|
-
├ λ /pvt/account/profile 1.98 kB
|
|
116
|
+
├ λ /pvt/account/profile 1.98 kB 142 kB
|
|
116
117
|
├ └ css/47f1b4e8de15d314.css 4.42 kB
|
|
117
|
-
├ λ /pvt/account/security 3.96 kB
|
|
118
|
+
├ λ /pvt/account/security 3.96 kB 144 kB
|
|
118
119
|
├ └ css/973dd40d4773e8cd.css 5.74 kB
|
|
119
|
-
├ λ /pvt/account/user-details 1.91 kB
|
|
120
|
+
├ λ /pvt/account/user-details 1.91 kB 142 kB
|
|
120
121
|
├ └ css/05c399956ff24b77.css 4.54 kB
|
|
121
122
|
└ ● /s 3.36 kB 158 kB
|
|
122
123
|
+ First Load JS shared by all 112 kB
|
|
123
124
|
├ chunks/framework-d514426edf885c68.js 45.4 kB
|
|
124
125
|
├ chunks/main-ec03882c4375091d.js 33.2 kB
|
|
125
|
-
├ chunks/pages/_app-
|
|
126
|
-
├ chunks/webpack-
|
|
126
|
+
├ chunks/pages/_app-3898f7fdf2646553.js 25.8 kB
|
|
127
|
+
├ chunks/webpack-5ac0858ff0030797.js 3.85 kB
|
|
127
128
|
└ css/0f070d03aacd9cc5.css 3.57 kB
|
|
128
129
|
|
|
129
130
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.96.
|
|
2
|
+
> @faststore/core@3.96.3 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> jest
|
|
4
4
|
|
|
5
|
-
PASS test/utils/multipleTemplates.test.ts (
|
|
6
|
-
PASS test/utils/
|
|
5
|
+
PASS test/utils/multipleTemplates.test.ts (30.887 s)
|
|
6
|
+
PASS test/utils/clearCookies.test.ts (31.406 s)
|
|
7
|
+
PASS test/utils/cookieCacheBusting.test.ts
|
|
7
8
|
PASS test/server/cms/global.test.ts
|
|
8
9
|
PASS test/server/cms/index.test.ts
|
|
9
|
-
PASS test/server/index.test.ts (
|
|
10
|
+
PASS test/server/index.test.ts (36.367 s)
|
|
11
|
+
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
|
|
10
12
|
|
|
11
|
-
Test Suites:
|
|
12
|
-
Tests:
|
|
13
|
+
Test Suites: 6 passed, 6 total
|
|
14
|
+
Tests: 47 passed, 47 total
|
|
13
15
|
Snapshots: 0 total
|
|
14
|
-
Time:
|
|
16
|
+
Time: 37.886 s
|
|
15
17
|
Ran all test suites.
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
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
|
+
## [3.96.4-dev.0](https://github.com/vtex/faststore/compare/v3.96.3...v3.96.4-dev.0) (2026-01-21)
|
|
7
|
+
|
|
8
|
+
# 3.96.0-dev.22 (2026-01-21)
|
|
9
|
+
|
|
10
|
+
**Note:** Version bump only for package @faststore/core
|
|
11
|
+
|
|
12
|
+
## [3.96.3](https://github.com/vtex/faststore/compare/v3.96.2...v3.96.3) (2026-01-21)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @faststore/core
|
|
15
|
+
|
|
6
16
|
## [3.96.2](https://github.com/vtex/faststore/compare/v3.96.1...v3.96.2) (2026-01-14)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @faststore/core
|
|
@@ -17,6 +27,28 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
17
27
|
|
|
18
28
|
- version 20251223 ([#3161](https://github.com/vtex/faststore/issues/3161)) ([ad5e8d1](https://github.com/vtex/faststore/commit/ad5e8d12fe45f1fb8e1134165172bf1c6b2a91e2))
|
|
19
29
|
|
|
30
|
+
# 3.96.0-dev.22 (2026-01-21)
|
|
31
|
+
|
|
32
|
+
**Note:** Version bump only for package @faststore/core
|
|
33
|
+
|
|
34
|
+
# [3.96.0-dev.21](https://github.com/vtex/faststore/compare/v3.96.0-dev.20...v3.96.0-dev.21) (2026-01-08)
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
- Prevent Partytown cross-origin errors in iframe environments ([#3155](https://github.com/vtex/faststore/issues/3155)) ([997252e](https://github.com/vtex/faststore/commit/997252e9a18807f4c26c350197d4f2d139de58f8))
|
|
39
|
+
|
|
40
|
+
# [3.96.0-dev.20](https://github.com/vtex/faststore/compare/v3.96.0-dev.19...v3.96.0-dev.20) (2026-01-08)
|
|
41
|
+
|
|
42
|
+
### Bug Fixes
|
|
43
|
+
|
|
44
|
+
- Add slug field to landing page schema - CROC-185 ([#3166](https://github.com/vtex/faststore/issues/3166)) ([41b9878](https://github.com/vtex/faststore/commit/41b987825ee5ebb7d311eef33e2ca65034dc130d))
|
|
45
|
+
|
|
46
|
+
# [3.96.0-dev.19](https://github.com/vtex/faststore/compare/v3.96.0-dev.18...v3.96.0-dev.19) (2026-01-08)
|
|
47
|
+
|
|
48
|
+
### Features
|
|
49
|
+
|
|
50
|
+
- logout clear storage ([#3163](https://github.com/vtex/faststore/issues/3163)) ([1fbacc3](https://github.com/vtex/faststore/commit/1fbacc3b3e32b4f83a2f56c1f97eb0f8ff843f61))
|
|
51
|
+
|
|
20
52
|
# 3.96.0-dev.18 (2025-12-24)
|
|
21
53
|
|
|
22
54
|
**Note:** Version bump only for package @faststore/core
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "3.96.
|
|
3
|
+
"version": "3.96.4-dev.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"@envelop/graphql-jit": "^8.0.3",
|
|
52
52
|
"@envelop/parser-cache": "^6.0.2",
|
|
53
53
|
"@envelop/validation-cache": "^6.0.2",
|
|
54
|
-
"@faststore/api": "3.96.
|
|
55
|
-
"@faststore/graphql-utils": "^3.96.0",
|
|
56
|
-
"@faststore/lighthouse": "3.96.0",
|
|
57
|
-
"@faststore/sdk": "3.96.0",
|
|
58
|
-
"@faststore/ui": "3.96.0",
|
|
54
|
+
"@faststore/api": "3.96.4-dev.0",
|
|
55
|
+
"@faststore/graphql-utils": "^3.96.4-dev.0",
|
|
56
|
+
"@faststore/lighthouse": "3.96.4-dev.0",
|
|
57
|
+
"@faststore/sdk": "3.96.4-dev.0",
|
|
58
|
+
"@faststore/ui": "3.96.4-dev.0",
|
|
59
59
|
"@graphql-codegen/cli": "5.0.2",
|
|
60
60
|
"@graphql-codegen/client-preset": "4.2.6",
|
|
61
61
|
"@graphql-codegen/typescript": "4.0.7",
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"ts-jest": "29.1.1",
|
|
124
124
|
"typescript": "5.3.2"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "e9e8720245637fc18616bdfbac78de7435dba622"
|
|
127
127
|
}
|
|
@@ -37,7 +37,10 @@ function ThirdPartyScripts() {
|
|
|
37
37
|
{includeGTM && <GoogleTagManager containerId={gtmContainerId} />}
|
|
38
38
|
{includeVTEX && <VTEX />}
|
|
39
39
|
<OverrideComponents.ThirdPartyScripts />
|
|
40
|
-
|
|
40
|
+
{/* Only render Partytown when not in an iframe to prevent cross-origin errors. */}
|
|
41
|
+
{typeof window !== 'undefined' && window.self === window.top && (
|
|
42
|
+
<Partytown key="partytown" />
|
|
43
|
+
)}
|
|
41
44
|
</>
|
|
42
45
|
)
|
|
43
46
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { SlideOver, useFadeEffect } from '@faststore/ui'
|
|
2
2
|
|
|
3
3
|
import { useSession } from 'src/sdk/session'
|
|
4
|
+
import {
|
|
5
|
+
expireCookieClient,
|
|
6
|
+
getCookieDomains,
|
|
7
|
+
getCookiePaths,
|
|
8
|
+
getVtexCookieNames,
|
|
9
|
+
} from 'src/utils/clearCookies'
|
|
4
10
|
import storeConfig from '../../../../../discovery.config'
|
|
5
11
|
import { ProfileSummary } from '../ProfileSummary/ProfileSummary'
|
|
6
12
|
import { OrganizationDrawerBody } from './OrganizationDrawerBody'
|
|
@@ -13,11 +19,105 @@ type OrganizationDrawerProps = {
|
|
|
13
19
|
isRepresentative: boolean
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
const clearBrowserStorageForCurrentDomain = async () => {
|
|
23
|
+
if (typeof window === 'undefined' || !storeConfig) return
|
|
24
|
+
|
|
25
|
+
// Clear Faststore-specific sessionStorage keys
|
|
26
|
+
try {
|
|
27
|
+
const sessionStorageKeys = [
|
|
28
|
+
'faststore_session_ready',
|
|
29
|
+
'faststore_auth_cookie_value',
|
|
30
|
+
'faststore_cache_bust_last_value',
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for (const key of sessionStorageKeys) {
|
|
34
|
+
try {
|
|
35
|
+
window.sessionStorage?.removeItem(key)
|
|
36
|
+
} catch {}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Remove all keys starting with __fs_gallery_page_ (used for PLP pagination)
|
|
40
|
+
try {
|
|
41
|
+
const keysToRemove: string[] = []
|
|
42
|
+
for (let i = 0; i < window.sessionStorage.length; i++) {
|
|
43
|
+
const key = window.sessionStorage.key(i)
|
|
44
|
+
if (key && key.startsWith('__fs_gallery_page_')) {
|
|
45
|
+
keysToRemove.push(key)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const key of keysToRemove) {
|
|
49
|
+
try {
|
|
50
|
+
window.sessionStorage.removeItem(key)
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
} catch {}
|
|
54
|
+
} catch {}
|
|
55
|
+
|
|
56
|
+
// Clear all cookies containing 'vtex' in the name (case-insensitive)
|
|
57
|
+
try {
|
|
58
|
+
const hostname = window.location.hostname
|
|
59
|
+
const secure = window.location.protocol === 'https:'
|
|
60
|
+
|
|
61
|
+
// Extract all cookie names from document.cookie
|
|
62
|
+
const allCookieNames = document.cookie
|
|
63
|
+
.split(';')
|
|
64
|
+
.map((c) => c.trim())
|
|
65
|
+
.filter(Boolean)
|
|
66
|
+
.map((c) => c.split('=')[0])
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
|
|
69
|
+
const vtexCookieNames = getVtexCookieNames(allCookieNames)
|
|
70
|
+
const paths = getCookiePaths(window.location.pathname || '/')
|
|
71
|
+
const domains = getCookieDomains(hostname)
|
|
72
|
+
|
|
73
|
+
for (const name of vtexCookieNames) {
|
|
74
|
+
for (const path of paths) {
|
|
75
|
+
for (const domain of domains) {
|
|
76
|
+
try {
|
|
77
|
+
expireCookieClient({ name, path, domain, secure })
|
|
78
|
+
} catch {}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} catch {}
|
|
83
|
+
|
|
84
|
+
// Clear IndexedDB (keyval-store)
|
|
85
|
+
try {
|
|
86
|
+
if (!('indexedDB' in window)) return
|
|
87
|
+
|
|
88
|
+
const idb = window.indexedDB
|
|
89
|
+
if (!idb) return
|
|
90
|
+
|
|
91
|
+
await new Promise<void>((resolve) => {
|
|
92
|
+
const req = idb.deleteDatabase('keyval-store')
|
|
93
|
+
req.onsuccess = () => resolve()
|
|
94
|
+
req.onerror = () => resolve()
|
|
95
|
+
req.onblocked = () => resolve()
|
|
96
|
+
})
|
|
97
|
+
} catch {}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const doLogout = async (_event?: unknown) => {
|
|
17
101
|
if (!storeConfig) return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// Clear client-side storage (sessionStorage, localStorage, IndexedDB, non-HttpOnly cookies)
|
|
105
|
+
await clearBrowserStorageForCurrentDomain()
|
|
106
|
+
|
|
107
|
+
// Clear HttpOnly cookies via API endpoint (server-side)
|
|
108
|
+
try {
|
|
109
|
+
await fetch('/api/fs/logout', {
|
|
110
|
+
method: 'POST',
|
|
111
|
+
credentials: 'include',
|
|
112
|
+
})
|
|
113
|
+
} catch {
|
|
114
|
+
// Continue even if API call fails
|
|
115
|
+
}
|
|
116
|
+
} finally {
|
|
117
|
+
window.location.assign(
|
|
118
|
+
`${storeConfig.secureSubdomain}/api/vtexid/pub/logout?scope=${storeConfig.api.storeId}&returnUrl=${storeConfig.storeUrl}`
|
|
119
|
+
)
|
|
120
|
+
}
|
|
21
121
|
}
|
|
22
122
|
|
|
23
123
|
export const OrganizationDrawer = ({
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { parse } from 'cookie'
|
|
2
|
+
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
|
3
|
+
|
|
4
|
+
import discoveryConfig from 'discovery.config'
|
|
5
|
+
import {
|
|
6
|
+
expireCookieServer,
|
|
7
|
+
getCookieDomains,
|
|
8
|
+
getVtexCookieNames,
|
|
9
|
+
} from 'src/utils/clearCookies'
|
|
10
|
+
|
|
11
|
+
const ADDITIONAL_COOKIES = ['CheckoutOrderFormOwnership'] as const
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Clears all cookies containing 'vtex' in the name (case-insensitive) + ADDITIONAL_COOKIES
|
|
15
|
+
* This endpoint handles HttpOnly cookies that cannot be cleared via JavaScript
|
|
16
|
+
*/
|
|
17
|
+
const handler: NextApiHandler = async (
|
|
18
|
+
request: NextApiRequest,
|
|
19
|
+
response: NextApiResponse
|
|
20
|
+
) => {
|
|
21
|
+
if (request.method !== 'POST') {
|
|
22
|
+
response.status(405).end()
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const hostname = request.headers.host?.split(':')[0] ?? ''
|
|
28
|
+
const cookies = parse(request.headers.cookie ?? '')
|
|
29
|
+
const domains = getCookieDomains(hostname)
|
|
30
|
+
const clearedCookies: string[] = []
|
|
31
|
+
|
|
32
|
+
const vtexCookieNames = getVtexCookieNames(Object.keys(cookies))
|
|
33
|
+
|
|
34
|
+
// Clear vid_rt cookie with specific path (only if refreshToken is enabled)
|
|
35
|
+
if (discoveryConfig.experimental?.refreshToken && cookies.vid_rt) {
|
|
36
|
+
for (const domain of domains) {
|
|
37
|
+
const clearedCookie = expireCookieServer({
|
|
38
|
+
name: 'vid_rt',
|
|
39
|
+
path: '/api/vtexid/refreshtoken/webstore',
|
|
40
|
+
domain,
|
|
41
|
+
})
|
|
42
|
+
clearedCookies.push(clearedCookie)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Clear other cookies with path /
|
|
47
|
+
const otherCookieNames = [
|
|
48
|
+
...vtexCookieNames,
|
|
49
|
+
...ADDITIONAL_COOKIES.filter((name) => cookies[name]),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
for (const cookieName of otherCookieNames) {
|
|
53
|
+
for (const domain of domains) {
|
|
54
|
+
const clearedCookie = expireCookieServer({
|
|
55
|
+
name: cookieName,
|
|
56
|
+
path: '/',
|
|
57
|
+
domain,
|
|
58
|
+
})
|
|
59
|
+
clearedCookies.push(clearedCookie)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (clearedCookies.length > 0) {
|
|
64
|
+
response.setHeader('set-cookie', clearedCookies)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
response.status(200).json({ success: true })
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('Error clearing cookies:', error)
|
|
70
|
+
response
|
|
71
|
+
.status(500)
|
|
72
|
+
.json({ success: false, error: 'Failed to clear cookies' })
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default handler
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
type ExpireCookieClientParams = {
|
|
2
|
+
name: string
|
|
3
|
+
path: string
|
|
4
|
+
domain?: string
|
|
5
|
+
secure?: boolean
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type ExpireCookieServerParams = {
|
|
9
|
+
name: string
|
|
10
|
+
path: string
|
|
11
|
+
domain?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Client-side: Expires a cookie by setting it to expire in the past
|
|
16
|
+
*/
|
|
17
|
+
export const expireCookieClient = ({
|
|
18
|
+
name,
|
|
19
|
+
path,
|
|
20
|
+
domain,
|
|
21
|
+
secure = false,
|
|
22
|
+
}: ExpireCookieClientParams): void => {
|
|
23
|
+
const domainAttr = domain ? `; domain=${domain}` : ''
|
|
24
|
+
const secureAttr = secure ? '; secure' : ''
|
|
25
|
+
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; max-age=0; path=${path}${domainAttr}; samesite=lax${secureAttr}`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Server-side: Generates a Set-Cookie header string to expire a cookie
|
|
30
|
+
*/
|
|
31
|
+
export const expireCookieServer = ({
|
|
32
|
+
name,
|
|
33
|
+
path,
|
|
34
|
+
domain,
|
|
35
|
+
}: ExpireCookieServerParams): string => {
|
|
36
|
+
const domainAttr = domain ? `; domain=${domain}` : ''
|
|
37
|
+
return `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; max-age=0; path=${path}${domainAttr}; samesite=lax; httponly`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Utility functions for clearing cookies
|
|
42
|
+
* Shared logic between client-side and server-side cookie clearing
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Generates domain variations for cookie clearing
|
|
47
|
+
* Tries multiple domain combinations to ensure cookies are cleared regardless of how they were set
|
|
48
|
+
*/
|
|
49
|
+
export const getCookieDomains = (
|
|
50
|
+
hostname: string
|
|
51
|
+
): Array<string | undefined> => [
|
|
52
|
+
undefined, // host-only cookie
|
|
53
|
+
hostname,
|
|
54
|
+
hostname.startsWith('.') ? hostname : `.${hostname}`,
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Filters cookie names that contain 'vtex' (case-insensitive)
|
|
59
|
+
*/
|
|
60
|
+
export const getVtexCookieNames = (cookieNames: string[]): string[] => {
|
|
61
|
+
return cookieNames.filter((name) => name.toLowerCase().includes('vtex'))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generates paths to try when clearing cookies
|
|
66
|
+
* Includes root path and all parent paths from current pathname
|
|
67
|
+
*/
|
|
68
|
+
export const getCookiePaths = (pathname: string): string[] => {
|
|
69
|
+
const paths: string[] = ['/']
|
|
70
|
+
const pathParts = pathname.split('/').filter(Boolean)
|
|
71
|
+
|
|
72
|
+
let current = ''
|
|
73
|
+
for (const part of pathParts) {
|
|
74
|
+
current += `/${part}`
|
|
75
|
+
if (!paths.includes(current)) paths.push(current)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return paths
|
|
79
|
+
}
|