@vtex/faststore-plugin-buyer-portal 1.3.68 → 1.3.70
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/.github/workflows/release.yaml +34 -16
- package/CHANGELOG.md +17 -3
- package/package.json +1 -1
- package/src/features/org-units/components/OrgUnitsDropdownMenu/OrgUnitsDropdownMenu.tsx +0 -5
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/shared/utils/cookie.ts +43 -0
- package/src/features/shared/utils/logout.tsx +120 -4
|
@@ -12,7 +12,8 @@ permissions:
|
|
|
12
12
|
|
|
13
13
|
jobs:
|
|
14
14
|
release:
|
|
15
|
-
name: Release
|
|
15
|
+
name: Release (stable)
|
|
16
|
+
if: github.ref == 'refs/heads/main'
|
|
16
17
|
timeout-minutes: 15
|
|
17
18
|
runs-on: ubuntu-latest
|
|
18
19
|
|
|
@@ -40,35 +41,55 @@ jobs:
|
|
|
40
41
|
- name: Update npm to latest
|
|
41
42
|
run: npm install -g npm@latest
|
|
42
43
|
|
|
43
|
-
# --- Stable release (main branch) ---
|
|
44
|
-
|
|
45
44
|
- name: Generate CHANGELOG and update Version Const
|
|
46
|
-
if: github.ref == 'refs/heads/main'
|
|
47
45
|
run: yarn release
|
|
48
46
|
|
|
49
47
|
- name: Update version to patch
|
|
50
|
-
if: github.ref == 'refs/heads/main'
|
|
51
48
|
run: yarn version --patch
|
|
52
49
|
|
|
53
|
-
- name: Publish
|
|
54
|
-
if: github.ref == 'refs/heads/main'
|
|
50
|
+
- name: Publish
|
|
55
51
|
run: npm publish
|
|
56
52
|
|
|
57
|
-
- name: Push changes and tags
|
|
58
|
-
if: github.ref == 'refs/heads/main'
|
|
53
|
+
- name: Push changes and tags
|
|
59
54
|
run: git push --follow-tags
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
beta:
|
|
57
|
+
name: Release (beta)
|
|
58
|
+
if: github.ref == 'refs/heads/beta'
|
|
59
|
+
timeout-minutes: 15
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- name: Check out code
|
|
64
|
+
uses: actions/checkout@v4
|
|
65
|
+
with:
|
|
66
|
+
fetch-depth: 2
|
|
67
|
+
|
|
68
|
+
- name: Setup Node.js environment
|
|
69
|
+
uses: actions/setup-node@v4
|
|
70
|
+
with:
|
|
71
|
+
node-version: '24'
|
|
72
|
+
cache: "yarn"
|
|
73
|
+
registry-url: "https://registry.npmjs.org"
|
|
74
|
+
|
|
75
|
+
- name: Configure CI Git User
|
|
76
|
+
run: |
|
|
77
|
+
git config user.name vtexgithubbot
|
|
78
|
+
git config user.email vtexgithubbot@github.com
|
|
79
|
+
|
|
80
|
+
- name: Install dependencies
|
|
81
|
+
run: yarn install --ignore-engines
|
|
82
|
+
|
|
83
|
+
- name: Update npm to latest
|
|
84
|
+
run: npm install -g npm@latest
|
|
62
85
|
|
|
63
86
|
- name: Get current version
|
|
64
|
-
if: github.ref == 'refs/heads/beta'
|
|
65
87
|
id: get_version
|
|
66
88
|
run: |
|
|
67
89
|
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
68
90
|
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
69
91
|
|
|
70
92
|
- name: Generate experimental version
|
|
71
|
-
if: github.ref == 'refs/heads/beta'
|
|
72
93
|
id: generate_version
|
|
73
94
|
run: |
|
|
74
95
|
BASE_VERSION=$(echo "${{ steps.get_version.outputs.current_version }}" | sed -E 's/(-.*)?$//')
|
|
@@ -78,15 +99,12 @@ jobs:
|
|
|
78
99
|
echo "Publishing experimental version: $EXPERIMENTAL_VERSION"
|
|
79
100
|
|
|
80
101
|
- name: Update package.json version
|
|
81
|
-
if: github.ref == 'refs/heads/beta'
|
|
82
102
|
run: npm version ${{ steps.generate_version.outputs.experimental_version }} --no-git-tag-version
|
|
83
103
|
|
|
84
104
|
- name: Publish experimental version
|
|
85
|
-
if: github.ref == 'refs/heads/beta'
|
|
86
105
|
run: npm publish --tag experimental
|
|
87
106
|
|
|
88
|
-
- name: Push changes
|
|
89
|
-
if: github.ref == 'refs/heads/beta'
|
|
107
|
+
- name: Push changes
|
|
90
108
|
run: |
|
|
91
109
|
git add package.json
|
|
92
110
|
git commit -m "chore: publish experimental version ${{ steps.generate_version.outputs.experimental_version }}" || echo "No changes to commit"
|
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [1.3.
|
|
10
|
+
## [1.3.70] - 2026-03-11
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
13
|
+
|
|
14
|
+
- Remove "Add Address" button from organizational units dropdown menu
|
|
15
|
+
|
|
16
|
+
## [1.3.69] - 2026-03-09
|
|
11
17
|
|
|
12
18
|
### Fixed
|
|
13
19
|
|
|
14
20
|
- Unify release workflow for NPM Trusted Publishers
|
|
21
|
+
- Clear cookies on logout
|
|
22
|
+
|
|
23
|
+
## [1.3.68] - 2026-03-05
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Skipped version
|
|
15
28
|
|
|
16
29
|
## [1.3.67] - 2026-03-05
|
|
17
30
|
|
|
@@ -501,7 +514,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
501
514
|
- Add CHANGELOG file
|
|
502
515
|
- Add README file
|
|
503
516
|
|
|
504
|
-
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/
|
|
517
|
+
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.70...HEAD
|
|
505
518
|
[1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
|
|
506
519
|
[1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
|
|
507
520
|
[1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
|
|
@@ -569,4 +582,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
569
582
|
[1.3.65]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.64...v1.3.65
|
|
570
583
|
[1.3.64]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.64
|
|
571
584
|
|
|
572
|
-
[1.3.
|
|
585
|
+
[1.3.70]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.69...v1.3.70
|
|
586
|
+
[1.3.69]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.69
|
package/package.json
CHANGED
|
@@ -71,11 +71,6 @@ export const OrgUnitsDropdownMenu = ({
|
|
|
71
71
|
Add Organizational Unit
|
|
72
72
|
</DropdownItem>
|
|
73
73
|
<BasicDropdownMenu.Separator />
|
|
74
|
-
<DropdownItem>
|
|
75
|
-
<Icon name="LocalPostOffice" {...sizeProps} />
|
|
76
|
-
Add Address
|
|
77
|
-
</DropdownItem>
|
|
78
|
-
<BasicDropdownMenu.Separator />
|
|
79
74
|
</>
|
|
80
75
|
)}
|
|
81
76
|
<DropdownItem
|
|
@@ -19,6 +19,13 @@ export interface ParsedCookie {
|
|
|
19
19
|
jti: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
type ExpireCookieClientParams = {
|
|
23
|
+
name: string;
|
|
24
|
+
path: string;
|
|
25
|
+
domain?: string;
|
|
26
|
+
secure?: boolean;
|
|
27
|
+
};
|
|
28
|
+
|
|
22
29
|
export function getAuthCookie(data: LoaderData) {
|
|
23
30
|
const authCookie =
|
|
24
31
|
data?.req?.cookies[`${AUT_COOKIE_KEY}_${storeConfig?.api.storeId}`] ?? "";
|
|
@@ -91,3 +98,39 @@ export function getCookieAsString(cookie: Record<string, string>): string {
|
|
|
91
98
|
function parseJwt(token: string): ParsedCookie {
|
|
92
99
|
return JSON.parse(Buffer.from(token.split(".")[1], "base64").toString());
|
|
93
100
|
}
|
|
101
|
+
|
|
102
|
+
export const getVtexCookieNames = (cookieNames: string[]): string[] => {
|
|
103
|
+
return cookieNames.filter((name) => name.toLowerCase().includes("vtex"));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const getCookiePaths = (pathname: string): string[] => {
|
|
107
|
+
const paths: string[] = ["/"];
|
|
108
|
+
const pathParts = pathname.split("/").filter(Boolean);
|
|
109
|
+
|
|
110
|
+
let current = "";
|
|
111
|
+
for (const part of pathParts) {
|
|
112
|
+
current += `/${part}`;
|
|
113
|
+
if (!paths.includes(current)) paths.push(current);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return paths;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const getCookieDomains = (
|
|
120
|
+
hostname: string
|
|
121
|
+
): Array<string | undefined> => [
|
|
122
|
+
undefined, // host-only cookie
|
|
123
|
+
hostname,
|
|
124
|
+
hostname.startsWith(".") ? hostname : `.${hostname}`,
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
export const expireCookieClient = ({
|
|
128
|
+
name,
|
|
129
|
+
path,
|
|
130
|
+
domain,
|
|
131
|
+
secure = false,
|
|
132
|
+
}: ExpireCookieClientParams): void => {
|
|
133
|
+
const domainAttr = domain ? `; domain=${domain}` : "";
|
|
134
|
+
const secureAttr = secure ? "; secure" : "";
|
|
135
|
+
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; max-age=0; path=${path}${domainAttr}; samesite=lax${secureAttr}`;
|
|
136
|
+
};
|
|
@@ -1,7 +1,123 @@
|
|
|
1
1
|
import storeConfig from "discovery.config";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {
|
|
4
|
+
getCookiePaths,
|
|
5
|
+
getCookieDomains,
|
|
6
|
+
getVtexCookieNames,
|
|
7
|
+
expireCookieClient,
|
|
8
|
+
} from "./cookie";
|
|
9
|
+
|
|
10
|
+
const clearBrowserStorageForCurrentDomain = async () => {
|
|
11
|
+
if (typeof window === "undefined" || !storeConfig) return;
|
|
12
|
+
|
|
13
|
+
// Clear Faststore-specific sessionStorage keys
|
|
14
|
+
try {
|
|
15
|
+
const sessionStorageKeys = [
|
|
16
|
+
"faststore_session_ready",
|
|
17
|
+
"faststore_auth_cookie_value",
|
|
18
|
+
"faststore_cache_bust_last_value",
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
for (const key of sessionStorageKeys) {
|
|
22
|
+
try {
|
|
23
|
+
window.sessionStorage?.removeItem(key);
|
|
24
|
+
} catch {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Remove all keys starting with __fs_gallery_page_ (used for PLP pagination)
|
|
30
|
+
try {
|
|
31
|
+
const keysToRemove: string[] = [];
|
|
32
|
+
for (let i = 0; i < window.sessionStorage.length; i++) {
|
|
33
|
+
const key = window.sessionStorage.key(i);
|
|
34
|
+
if (key && key.startsWith("__fs_gallery_page_")) {
|
|
35
|
+
keysToRemove.push(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const key of keysToRemove) {
|
|
39
|
+
try {
|
|
40
|
+
window.sessionStorage.removeItem(key);
|
|
41
|
+
} catch {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Clear all cookies containing 'vtex' in the name (case-insensitive)
|
|
53
|
+
try {
|
|
54
|
+
const hostname = window.location.hostname;
|
|
55
|
+
const secure = window.location.protocol === "https:";
|
|
56
|
+
|
|
57
|
+
// Extract all cookie names from document.cookie
|
|
58
|
+
const allCookieNames = document.cookie
|
|
59
|
+
.split(";")
|
|
60
|
+
.map((c) => c.trim())
|
|
61
|
+
.filter(Boolean)
|
|
62
|
+
.map((c) => c.split("=")[0])
|
|
63
|
+
.filter(Boolean);
|
|
64
|
+
|
|
65
|
+
const vtexCookieNames = getVtexCookieNames(allCookieNames);
|
|
66
|
+
const paths = getCookiePaths(window.location.pathname || "/");
|
|
67
|
+
const domains = getCookieDomains(hostname);
|
|
68
|
+
|
|
69
|
+
for (const name of vtexCookieNames) {
|
|
70
|
+
for (const path of paths) {
|
|
71
|
+
for (const domain of domains) {
|
|
72
|
+
try {
|
|
73
|
+
expireCookieClient({ name, path, domain, secure });
|
|
74
|
+
} catch {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
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
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const doLogout = async () => {
|
|
103
|
+
if (!storeConfig) return;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
// Clear client-side storage (sessionStorage, localStorage, IndexedDB, non-HttpOnly cookies)
|
|
107
|
+
await clearBrowserStorageForCurrentDomain();
|
|
108
|
+
|
|
109
|
+
// Clear HttpOnly cookies via API endpoint (server-side)
|
|
110
|
+
try {
|
|
111
|
+
await fetch("/api/fs/logout", {
|
|
112
|
+
method: "POST",
|
|
113
|
+
credentials: "include",
|
|
114
|
+
});
|
|
115
|
+
} catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
} finally {
|
|
119
|
+
window.location.assign(
|
|
120
|
+
`${storeConfig.secureSubdomain}/api/vtexid/pub/logout?scope=${storeConfig.api.storeId}&returnUrl=${storeConfig.storeUrl}`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
7
123
|
};
|