@vtex/faststore-plugin-buyer-portal 1.3.67 → 1.3.69

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.
@@ -1,18 +1,19 @@
1
- # This Action should run on main branch and verify lint, test, and then publish the version on npm
2
1
  name: CD
3
2
 
4
3
  on:
5
4
  push:
6
5
  branches:
7
6
  - main
7
+ - beta
8
8
 
9
9
  permissions:
10
- id-token: write # Required for OIDC trusted publishing
10
+ id-token: write
11
11
  contents: write
12
12
 
13
13
  jobs:
14
- build:
15
- name: BuyerPortal
14
+ 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
 
@@ -48,10 +49,63 @@ jobs:
48
49
 
49
50
  - name: Publish
50
51
  run: npm publish
51
- # OIDC authentication is used automatically when trusted publishing is configured
52
52
 
53
53
  - name: Push changes and tags
54
+ run: git push --follow-tags
55
+
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
85
+
86
+ - name: Get current version
87
+ id: get_version
88
+ run: |
89
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
90
+ echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
91
+
92
+ - name: Generate experimental version
93
+ id: generate_version
94
+ run: |
95
+ BASE_VERSION=$(echo "${{ steps.get_version.outputs.current_version }}" | sed -E 's/(-.*)?$//')
96
+ TIMESTAMP=$(date +%Y%m%d%H%M%S)
97
+ EXPERIMENTAL_VERSION="${BASE_VERSION}-experimental.${TIMESTAMP}"
98
+ echo "experimental_version=$EXPERIMENTAL_VERSION" >> $GITHUB_OUTPUT
99
+ echo "Publishing experimental version: $EXPERIMENTAL_VERSION"
100
+
101
+ - name: Update package.json version
102
+ run: npm version ${{ steps.generate_version.outputs.experimental_version }} --no-git-tag-version
103
+
104
+ - name: Publish experimental version
105
+ run: npm publish --tag experimental
106
+
107
+ - name: Push changes
54
108
  run: |
55
- git config user.email "vtexgithubbot@github.com"
56
- git config user.name "vtexgithubbot"
57
- git push --follow-tags
109
+ git add package.json
110
+ git commit -m "chore: publish experimental version ${{ steps.generate_version.outputs.experimental_version }}" || echo "No changes to commit"
111
+ git push origin beta || echo "No changes to push"
package/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.69] - 2026-03-09
11
+
12
+ ### Fixed
13
+
14
+ - Unify release workflow for NPM Trusted Publishers
15
+ - Clear cookies on logout
16
+
17
+ ## [1.3.68] - 2026-03-05
18
+
19
+ ### Changed
20
+
21
+ - Skipped version
22
+
10
23
  ## [1.3.67] - 2026-03-05
11
24
 
12
25
  ### Changed
@@ -495,7 +508,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
495
508
  - Add CHANGELOG file
496
509
  - Add README file
497
510
 
498
- [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.67...HEAD
511
+ [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/1.3.69...HEAD
499
512
  [1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
500
513
  [1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
501
514
  [1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
@@ -562,3 +575,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
562
575
  [1.3.66]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.65...v1.3.66
563
576
  [1.3.65]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.64...v1.3.65
564
577
  [1.3.64]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.64
578
+
579
+ [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.67",
3
+ "version": "1.3.69",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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.67";
25
+ export const CURRENT_VERSION = "1.3.69";
@@ -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
  };
@@ -1,69 +0,0 @@
1
- # This Action runs on experimental branch and publishes an experimental version to npm
2
- name: CD Beta
3
-
4
- on:
5
- push:
6
- branches:
7
- - beta
8
-
9
- jobs:
10
- build:
11
- name: BuyerPortal Beta
12
- timeout-minutes: 15
13
- runs-on: ubuntu-latest
14
-
15
- steps:
16
- - name: Check out code
17
- uses: actions/checkout@v4
18
- with:
19
- fetch-depth: 2
20
-
21
- - name: Setup Node.js environment
22
- uses: actions/setup-node@v4
23
- with:
24
- node-version: 20
25
- cache: "yarn"
26
- registry-url: "https://registry.npmjs.org"
27
-
28
- - name: Configure CI Git User
29
- run: |
30
- git config user.name vtexgithubbot
31
- git config user.email vtexgithubbot@github.com
32
-
33
- - name: Install dependencies
34
- run: yarn
35
-
36
- - name: Get current version
37
- id: get_version
38
- run: |
39
- CURRENT_VERSION=$(node -p "require('./package.json').version")
40
- echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
41
-
42
- - name: Generate experimental version
43
- id: generate_version
44
- run: |
45
- # Extract base version (remove any existing prerelease suffix)
46
- BASE_VERSION=$(echo "${{ steps.get_version.outputs.current_version }}" | sed -E 's/(-.*)?$//')
47
- # Generate timestamp-based identifier
48
- TIMESTAMP=$(date +%Y%m%d%H%M%S)
49
- # Create experimental version
50
- EXPERIMENTAL_VERSION="${BASE_VERSION}-experimental.${TIMESTAMP}"
51
- echo "experimental_version=$EXPERIMENTAL_VERSION" >> $GITHUB_OUTPUT
52
- echo "Publishing experimental version: $EXPERIMENTAL_VERSION"
53
-
54
- - name: Update package.json version
55
- run: |
56
- npm version ${{ steps.generate_version.outputs.experimental_version }} --no-git-tag-version
57
-
58
- - name: Publish experimental version
59
- run: yarn publish --non-interactive --tag experimental
60
- env:
61
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
62
-
63
- - name: Push changes and tags
64
- run: |
65
- git config user.email "vtexgithubbot@github.com"
66
- git config user.name "vtexgithubbot"
67
- git add package.json
68
- git commit -m "chore: publish experimental version ${{ steps.generate_version.outputs.experimental_version }}" || echo "No changes to commit"
69
- git push origin experimental || echo "No changes to push"