@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.
@@ -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 stable release
54
- if: github.ref == 'refs/heads/main'
50
+ - name: Publish
55
51
  run: npm publish
56
52
 
57
- - name: Push changes and tags (stable)
58
- if: github.ref == 'refs/heads/main'
53
+ - name: Push changes and tags
59
54
  run: git push --follow-tags
60
55
 
61
- # --- Beta release (beta branch) ---
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 (beta)
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.68] - 2026-03-05
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/1.3.68...HEAD
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.68]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.68
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.3.68",
3
+ "version": "1.3.70",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
@@ -22,4 +22,4 @@ export const SCOPE_KEYS = {
22
22
  CREDIT_CARDS: "creditCards",
23
23
  } as const;
24
24
 
25
- export const CURRENT_VERSION = "1.3.68";
25
+ export const CURRENT_VERSION = "1.3.70";
@@ -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
- export const doLogout = () => {
4
- window.location.assign(
5
- `${storeConfig.secureSubdomain}/api/vtexid/pub/logout?scope=${storeConfig.api.storeId}&returnUrl=${storeConfig.storeUrl}`
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
  };