UNPKG

@auth0/auth0-spa-js

Version:

Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE

146 lines (114 loc) 3.48 kB
import * as Cookies from 'es-cookie'; interface ClientStorageOptions { daysUntilExpire?: number; cookieDomain?: string; } /** * Defines a type that handles storage to/from a storage location */ export type ClientStorage = { get<T extends Object>(key: string): T | undefined; save(key: string, value: any, options?: ClientStorageOptions): void; remove(key: string, options?: ClientStorageOptions): void; }; /** * A storage protocol for marshalling data to/from cookies */ export const CookieStorage = { get<T extends Object>(key: string) { const value = Cookies.get(key); if (typeof value === 'undefined') { return; } return <T>JSON.parse(value); }, save(key: string, value: any, options?: ClientStorageOptions): void { let cookieAttributes: Cookies.CookieAttributes = {}; if ('https:' === window.location.protocol) { cookieAttributes = { secure: true, sameSite: 'none' }; } if (options?.daysUntilExpire) { cookieAttributes.expires = options.daysUntilExpire; } if (options?.cookieDomain) { cookieAttributes.domain = options.cookieDomain; } Cookies.set(key, JSON.stringify(value), cookieAttributes); }, remove(key: string, options?: ClientStorageOptions) { let cookieAttributes: Cookies.CookieAttributes = {}; if (options?.cookieDomain) { cookieAttributes.domain = options.cookieDomain; } Cookies.remove(key, cookieAttributes); } } as ClientStorage; /** * @ignore */ const LEGACY_PREFIX = '_legacy_'; /** * Cookie storage that creates a cookie for modern and legacy browsers. * See: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients */ export const CookieStorageWithLegacySameSite = { get<T extends Object>(key: string) { const value = CookieStorage.get<T>(key); if (value) { return value; } return CookieStorage.get<T>(`${LEGACY_PREFIX}${key}`); }, save(key: string, value: any, options?: ClientStorageOptions): void { let cookieAttributes: Cookies.CookieAttributes = {}; if ('https:' === window.location.protocol) { cookieAttributes = { secure: true }; } if (options?.daysUntilExpire) { cookieAttributes.expires = options.daysUntilExpire; } if (options?.cookieDomain) { cookieAttributes.domain = options.cookieDomain; } Cookies.set( `${LEGACY_PREFIX}${key}`, JSON.stringify(value), cookieAttributes ); CookieStorage.save(key, value, options); }, remove(key: string, options?: ClientStorageOptions) { let cookieAttributes: Cookies.CookieAttributes = {}; if (options?.cookieDomain) { cookieAttributes.domain = options.cookieDomain; } Cookies.remove(key, cookieAttributes); CookieStorage.remove(key, options); CookieStorage.remove(`${LEGACY_PREFIX}${key}`, options); } } as ClientStorage; /** * A storage protocol for marshalling data to/from session storage */ export const SessionStorage = { get<T extends Object>(key: string) { /* c8 ignore next 3 */ if (typeof sessionStorage === 'undefined') { return; } const value = sessionStorage.getItem(key); if (value == null) { return; } return <T>JSON.parse(value); }, save(key: string, value: any): void { sessionStorage.setItem(key, JSON.stringify(value)); }, remove(key: string) { sessionStorage.removeItem(key); } } as ClientStorage;