@azure/msal-browser
Version:
Microsoft Authentication Library for js
108 lines (90 loc) • 2.98 kB
text/typescript
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
ClientAuthErrorCodes,
createClientAuthError,
} from "@azure/msal-common/browser";
import { IWindowStorage } from "./IWindowStorage.js";
// Cookie life calculation (hours * minutes * seconds * ms)
const COOKIE_LIFE_MULTIPLIER = 24 * 60 * 60 * 1000;
export const SameSiteOptions = {
Lax: "Lax",
None: "None",
} as const;
export type SameSiteOptions =
(typeof SameSiteOptions)[keyof typeof SameSiteOptions];
export class CookieStorage implements IWindowStorage<string> {
initialize(): Promise<void> {
return Promise.resolve();
}
getItem(key: string): string | null {
const name = `${encodeURIComponent(key)}`;
const cookieList = document.cookie.split(";");
for (let i = 0; i < cookieList.length; i++) {
const cookie = cookieList[i];
const [key, ...rest] = decodeURIComponent(cookie).trim().split("=");
const value = rest.join("=");
if (key === name) {
return value;
}
}
return "";
}
getUserData(): string | null {
throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented);
}
setItem(
key: string,
value: string,
cookieLifeDays?: number,
secure: boolean = true,
sameSite: SameSiteOptions = SameSiteOptions.Lax
): void {
let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(
value
)};path=/;SameSite=${sameSite};`;
if (cookieLifeDays) {
const expireTime = getCookieExpirationTime(cookieLifeDays);
cookieStr += `expires=${expireTime};`;
}
if (secure || sameSite === SameSiteOptions.None) {
// SameSite None requires Secure flag
cookieStr += "Secure;";
}
document.cookie = cookieStr;
}
async setUserData(): Promise<void> {
return Promise.reject(
createClientAuthError(ClientAuthErrorCodes.methodNotImplemented)
);
}
removeItem(key: string): void {
// Setting expiration to -1 removes it
this.setItem(key, "", -1);
}
getKeys(): string[] {
const cookieList = document.cookie.split(";");
const keys: Array<string> = [];
cookieList.forEach((cookie) => {
const cookieParts = decodeURIComponent(cookie).trim().split("=");
keys.push(cookieParts[0]);
});
return keys;
}
containsKey(key: string): boolean {
return this.getKeys().includes(key);
}
}
/**
* Get cookie expiration time
* @param cookieLifeDays
*/
export function getCookieExpirationTime(cookieLifeDays: number): string {
const today = new Date();
const expr = new Date(
today.getTime() + cookieLifeDays * COOKIE_LIFE_MULTIPLIER
);
return expr.toUTCString();
}