Skip to content

Commit

Permalink
Add LocalAndCookie storage
Browse files Browse the repository at this point in the history
  • Loading branch information
adamraya committed Dec 27, 2023
1 parent b5739d0 commit d69c58e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 5 deletions.
18 changes: 14 additions & 4 deletions packages/commerce-sdk-react/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ import {
} from 'commerce-sdk-isomorphic'
import {jwtDecode, JwtPayload} from 'jwt-decode'
import {ApiClientConfigParams, Prettify, RemoveStringIndex} from '../hooks/types'
import {BaseStorage, LocalStorage, CookieStorage, MemoryStorage, StorageType} from './storage'
import {
BaseStorage,
LocalStorage,
CookieStorage,
MemoryStorage,
StorageType,
LocalAndCookieStorage
} from './storage'
import {CustomerType} from '../hooks/useCustomerType'
import {getParentOrigin, isOriginTrusted, onClient} from '../utils'
import {onClient} from '../utils'

type TokenResponse = ShopperLoginTypes.TokenResponse
type Helpers = typeof helpers
Expand Down Expand Up @@ -106,14 +113,14 @@ const DATA_MAP: AuthDataMap = {
key: 'token_type'
},
refresh_token_guest: {
storageType: isOriginTrusted(getParentOrigin()) ? 'local' : 'cookie',
storageType: 'localandcookie',
key: 'cc-nx-g',
callback: (store) => {
store.delete('cc-nx')
}
},
refresh_token_registered: {
storageType: isOriginTrusted(getParentOrigin()) ? 'local' : 'cookie',
storageType: 'localandcookie',
key: 'cc-nx',
callback: (store) => {
store.delete('cc-nx-g')
Expand Down Expand Up @@ -199,6 +206,9 @@ class Auth {
this.stores = {
cookie: onClient() ? new CookieStorage(options) : new MemoryStorage(options),
local: onClient() ? new LocalStorage(options) : new MemoryStorage(options),
localandcookie: onClient()
? new LocalAndCookieStorage(options)
: new MemoryStorage(options),
memory: new MemoryStorage(options)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/commerce-sdk-react/src/auth/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

export type StorageType = 'cookie' | 'local' | 'memory'
export type StorageType = 'cookie' | 'local' | 'localandcookie' | 'memory'
export * from './base'
export * from './cookie'
export * from './local'
export * from './localandcookie'
export * from './memory'
68 changes: 68 additions & 0 deletions packages/commerce-sdk-react/src/auth/storage/localandcookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2023, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import {BaseStorage, BaseStorageOptions} from './base'
import Cookies from 'js-cookie'
import {getDefaultCookieAttributes} from '../../utils'

/**
* A normalized implementation for LocalStorage. It implements the BaseStorage interface
* which allows developers to easily switch between Cookie, LocalStorage, Memory store
* or a customized storage. This class is mainly used for commerce-sdk-react library
* to store authentication tokens.
*/
export class LocalAndCookieStorage extends BaseStorage {
constructor(options?: BaseStorageOptions) {
// TODO: Use detectLocalStorageAvailable when app can better handle clients without storage
if (typeof window === 'undefined' || typeof document === 'undefined') {
throw new Error('LocalAndCookieStorage is not available on the current environment.')
}
super(options)
}
set(key: string, value: string) {
const oldValue = this.get(key)
const suffixedKey = this.getSuffixedKey(key)
window.localStorage.setItem(suffixedKey, value)
Cookies.set(suffixedKey, value, {
...getDefaultCookieAttributes()
})
// Changes to localStorage automatically dispatch a storage event in every tab where a site
// is loaded, *except* the original tab that made the change. To allow our `useLocalStorage`
// hook to work in the originating tab, we must dispatch a copy of the event. This event is
// only seen by the originating tab. A key difference with this event is that `isTrusted` is
// false, but that should not impact our use case.
const event = new StorageEvent('storage', {
key: suffixedKey,
oldValue: oldValue,
newValue: value
})
window.dispatchEvent(event)
}
get(key: string) {
const suffixedKey = this.getSuffixedKey(key)
return window.localStorage.getItem(suffixedKey) || ''
}
delete(key: string) {
const suffixedKey = this.getSuffixedKey(key)
const oldValue = this.get(suffixedKey)
window.localStorage.removeItem(suffixedKey)
Cookies.remove(suffixedKey, {
...getDefaultCookieAttributes()
})
// Changes to localStorage automatically dispatch a storage event in every tab where a site
// is loaded, *except* the original tab that made the change. To allow our `useLocalStorage`
// hook to work in the originating tab, we must dispatch a copy of the event. This event is
// only seen by the originating tab. A key difference with this event is that `isTrusted` is
// false, but that should not impact our use case.
const event = new StorageEvent('storage', {
key: suffixedKey,
oldValue: oldValue,
newValue: null
})
window.dispatchEvent(event)
}
}

0 comments on commit d69c58e

Please sign in to comment.